Filter by property

Viewed 82893

Is it possible to filter a Django queryset by model property?

i have a method in my model:

@property
def myproperty(self):
    [..]

and now i want to filter by this property like:

MyModel.objects.filter(myproperty=[..])

is this somehow possible?

8 Answers

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())

I had the same problem, and I developed this simple solution:

objects = [
    my_object 
    for my_object in MyModel.objects.all() 
    if my_object.myProperty == [...]
]

This is not a performatic solution, it shouldn't be done in tables that contains a large amount of data. This is great for a simple solution or for a personal small project.

It may also be possible to use queryset annotations that duplicate the property get/set-logic, as suggested e.g. by @rattray and @thegrimmscientist, in conjunction with the property. This could yield something that works both on the Python level and on the database level.

Not sure about the drawbacks, however: see this SO question for an example.

Related