Skip to main content

Filters for django

Project description

__What it is:__

A lightweight package for django which does the filtering of django querysets. The central object - a filter - is a callable that takes a queryset as a parameter and returns a queryset:

filtered_queryset = filtr(Model.objects.all())

Django itself has a similar object - Q-object (`django.db.models.Q`). Q-objects can be combined toghether (with `|`, `&` operations) or inverted (`~`) and then passed to `queryset.filter`.

With `qfilters`, what you get in the most common case, is just a wrapper around the Q-object. However there are __2 features__ that may be the reasons to use the package:

__1. Support for additional filter types.__

For example, there is `ValuesDictFilter`, that is constructed from a field list, that will be passed to `queryset.values` and retrieve a list of dictionaries, and a filtering function, which accepts that dict as a parameter.

This filters can be combined or inverted in the same way Q-objects do, so that using multiple filters would result in a single call to `queryset.values`.

This is what it looks like in practice (all examples are taken from the `qfilter` testsuite):

@ValuesDictFilter('@', fields_list=['traits__good_hunter'])
def nas_i_zdes_neploho_kormyat(obj):
return obj['traits__good_hunter'] is False # because it can be None

cats = nas_i_zdes_neploho_kormyat(self.CatsBreed.objects.all())
assert cats.exists()

There are also exotic variants (`qfilters.exotic_types`) like `QuerysetIterationHook`, which appends attributes to objects when queryset is iterated over. Another one is `PropertyBasedFilter`, which can access object's attributes and even properties like it were a regular django model object. The implementation is not very straightforward, still it passes the tests so far. Here is what it looks like:

class CatsBreed(models.Model):
# ...
traits = models.OneToOneField('Traits')

class Traits(models.Model):
#...
weight_min = models.FloatField(u'Вес от, кг', null=True)
weight_max = models.FloatField(u'Вес до, кг', null=True)
# if you can't specify min and max
weight = models.FloatField(u'Вес, кг', null=True)

@property
def kg(self):
return self.weight or self.weight_max


from qfilters import PropertyBasedFilter

@PropertyBasedFilter('@',
fields_list=['traits__weight', 'traits__weight_max'],
properties=['traits.kg'])
def light_cats(obj):
return not obj.traits.kg or obj.traits.kg < 3

assert light_cats(CatsBreed.objects.all()).exists()

__2. Using class as container: methods are filters__

It is convenient to have an object, which can hold some context (for example, the view itself),
and let the methods be filters, and be able to access this context. `qfilters.containers` provide this functionality, specifically, there is a `MethodFilter` class:

from qfilter import MethodFilter

class ManyFilters(MethodFilter):

def filter__q(self):
return Q(name__in=[u'Сиамская', u'Норвежская лесная'])

@make_filter(PropertyBasedFilter,
fields_list=['traits__weight', 'traits__weight_max'],
properties=['traits.kg'])
def filter__big(self, cat):
return cat.traits.kg and cat.traits.kg > 5

def filter__q_yet_another(self):
return Q(name__in=[u'Персидская', u'Норвежская лесная'])

filters = ManyFilters()
cat = filters(CatsBreed.objects.all())[0]

The idea was born from the experience of using the [django-rest-framework](http://www.django-rest-framework.org/). There is a notion of filter backend (a class) which every view knows about. First I implemented a simple method-based filter backend, the possible return values for the methods were eiher a Q-object or a queryset. But then I got difficulties with debugging since the return value doesn't even know which method it came from. Thus, I decided it will be a good idea to have this filter obbject.

P.S. `qfilters` does not provide a filter backend to use with django-rest-framework, but it's a piece of cake to write one.

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qfilters-0.1.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

qfilters-0.1-py2.py3-none-any.whl (10.8 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file qfilters-0.1.tar.gz.

File metadata

  • Download URL: qfilters-0.1.tar.gz
  • Upload date:
  • Size: 7.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for qfilters-0.1.tar.gz
Algorithm Hash digest
SHA256 6eae82b12314fc1e088104207eb8278f2a21f5d05b679fc8c27bff4eba9f8eff
MD5 93e1cfb40b770e1aa9c1f72da805593e
BLAKE2b-256 7785e4b935a186ed3735bc96a1b703f7d5dde271fcb5559108a2d67b15ffa937

See more details on using hashes here.

File details

Details for the file qfilters-0.1-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for qfilters-0.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 133dec0f29b65e4e0bd4d53642311b9a35717e10433382a9dbdf3e0a7af1c128
MD5 a1eafa2b7a3a7fc35eb935c5e9005b79
BLAKE2b-256 e84c98679171705941f1c9c547e1e71e32f2ffb2962e1539ec5339ab02969da9

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page