Filter by property
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.