Filter by property Filter by property python python

Filter by property


Nope. Django filters operate at the database level, generating SQL. To filter based on Python properties, you have to load the object into Python to evaluate the property--and at that point, you've already done all the work to load it.


I might be misunderstanding your original question, but there is a filter builtin in python.

filtered = filter(myproperty, MyModel.objects)

But it's better to use a list comprehension:

filtered = [x for x in MyModel.objects if x.myproperty()]

or even better, a generator expression:

filtered = (x for x in MyModel.objects if x.myproperty())


Riffing off @TheGrimmScientist's suggested workaround, you can make these "sql properties" by defining them on the Manager or the QuerySet, and reuse/chain/compose them:

With a Manager:

class CompanyManager(models.Manager):    def with_chairs_needed(self):        return self.annotate(chairs_needed=F('num_employees') - F('num_chairs'))class Company(models.Model):    # ...    objects = CompanyManager()Company.objects.with_chairs_needed().filter(chairs_needed__lt=4)

With a QuerySet:

class CompanyQuerySet(models.QuerySet):    def many_employees(self, n=50):        return self.filter(num_employees__gte=n)    def needs_fewer_chairs_than(self, n=5):        return self.with_chairs_needed().filter(chairs_needed__lt=n)    def with_chairs_needed(self):        return self.annotate(chairs_needed=F('num_employees') - F('num_chairs'))class Company(models.Model):    # ...    objects = CompanyQuerySet.as_manager()Company.objects.needs_fewer_chairs_than(4).many_employees()

See https://docs.djangoproject.com/en/1.9/topics/db/managers/ for more. Note that I am going off the documentation and have not tested the above.