Filtering on a model's calculated method using django_filter

django, django-filter, django-rest-framework, methods

Solution

`incremented` is not a field (i.e an instance of `Field`) on that model, it is just a python function. On the database side of things, it doesn't exist, so can't be filtered on.

Until #14030 is fixed, you can't filter on calculated values like this easily, you have to use `extra`. So for example to get all objects with `number` of 2 via `incremented`:

MyModel.objects.extra(where=['number + 1 = %s'], params=[3])

To use that with the `django-filter` library, you'll need to override the `action` of your `Filter`:

def action(query, value):
    return query.extra(where=['number + 1 = %s'], params=[value])

class F(django_filters.FilterSet):
    incremented = django_filters.NumberFilter(action=action)
    class Meta:
        model = MyModel
        fields = ['incremented']

Problem

I have a Django model with a calculated field on it. As an example: ``` class MyModel(models.Model): number = models.IntegerField(default=3) @property def incremented(self): return self.number + 1 ``` I'd like to filter on this property, so I tried the following: ``` class ModelFilter(django_filter.FilterSet): class Meta: model = MyModel fields = ('incremented',) ``` That did not work, and neither did this: ``` class ModelFilter(django_filter.FilterSet): incremented = django_filter.NumberFilter(lookup_type='exact') class Meta: model = MyModel fields = ('incremented',) ``` What am I doing wrong here?

Original source