Django-filter 2 使用@property来过滤?



我有这个过滤器:

class SchoolFilter(django_filters.FilterSet):
class Meta:
model = School
fields = {
'name': ['icontains'],
'special_id': ['icontains'],
}

其中special_id是学校模式的@property:

@property
def special_id(self):
type = self.type
unique_id = self.unique_id
code = self.code
if unique_id < 10:
unique_id = f'0{unique_id}'
if int(self.code) < 10:
code = f'0{self.code}'
special_id = f'{code}{type}{id}'
return special_id

我试图用谷歌搜索一些答案,但找不到任何东西。现在,如果我像我一样使用过滤器,我只收到此错误:

'Meta.fields' contains fields that are not defined on this FilterSet: special_id

如何将属性定义为此筛选器集的字段?我甚至可以将 django 过滤器与@property一起使用吗?

感谢您的任何回答!

更新:

想通了。不是最漂亮的解决方案,但 ayyy

class SchoolFilter(django_filters.FilterSet):
special_id = django_filters.CharFilter(field_name="special_id", method="special_id_filter", label="Special School ID")
def special_id_filter(self, queryset, name, value):
schools_pk = []
for obj in queryset:
if obj.special_id == value:
schools_pk.append(obj.pk)
queryset = queryset.filter(pk__in=schools_pk)
return queryset
class Meta:
model = School
fields = {
'name': ['icontains'],
'special_id': ['icontains'],
}

你不能。FilterSet 将仅筛选实际字段,因为 FilterSet 会更改 QuerySet。

QuerySet 根据应用的筛选器执行数据库调用,这意味着您只能筛选实际存储在数据库中的字段。

您可以批注 QuerySet 以添加special_id,但像这样的批注链接在一起非常复杂。

更好的方法是在 FilterSet 上创建自定义过滤器,但我不确定如何做到这一点。如果你能解释special_id是什么,以及你为什么要通过icontains搜索它,那么我也许可以为你指出正确的方向。

这是MethodFilter的实现,我认为它与您想要的类似。

>FilterSet通过过滤查询集(将 where 条件添加到底层 sql(来操作。这意味着,FilterSet只能对数据库中存在的Columns进行操作。这里的special_id是一个计算属性(它不是列,它是使用其他字段/列动态计算的(,所以它不起作用。

解决方法是使special_id成为普通字段/列,在运行时计算值并在保存时写入数据库。

最新更新