使用django_filter过滤模型的计算方法

jdo*_*dot 2 django methods django-filter django-rest-framework

我有一个带有计算字段的Django模型.举个例子:

class MyModel(models.Model):
    number = models.IntegerField(default=3)

    @property
    def incremented(self):
        return self.number + 1
Run Code Online (Sandbox Code Playgroud)

我想过滤这个属性,所以我尝试了以下内容:

class ModelFilter(django_filter.FilterSet):
    class Meta:
        model = MyModel
        fields = ('incremented',)
Run Code Online (Sandbox Code Playgroud)

那不起作用,也没有这样做:

class ModelFilter(django_filter.FilterSet):
    incremented = django_filter.NumberFilter(lookup_type='exact')
    class Meta:
        model = MyModel
        fields = ('incremented',)
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?

Jam*_*urn 6

incremented不是Field该模型的字段(即实例),它只是一个python函数.在数据库方面,它不存在,因此无法过滤.

#14030修复之前,您无法轻松过滤这样的计算值,您必须使用extra.因此,例如通过以下方式获取所有具有number2的对象incremented:

MyModel.objects.extra(where=['number + 1 = %s'], params=[3])
Run Code Online (Sandbox Code Playgroud)

要在django-filter库中使用它,您需要覆盖以下action内容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']
Run Code Online (Sandbox Code Playgroud)