你好,
我正在使用 django-filter 和 django-rest-framework,这个不起作用,它什么也不返回:
import django_filters
from rest_framework import filters
from ..models import MyModel
class MyModelFilter(filters.FilterSet):
my_field = django_filters.CharFilter(lookup_expr='in')
class Meta:
model = MyModel
但是这个确实可以按预期工作:
from django_filters import filters as df_filters
from rest_framework import filters
from ..models import MyModel
class CharInFilter(df_filters.BaseInFilter, df_filters.CharFilter):
pass
class MyModelFilter(filters.FilterSet):
my_field = CharInFilter()
class Meta:
model = MyModel
这是正常和预期的行为,还是我在这里做错了什么? 谢谢。
嗨@maxtepkeev。 是的 - 这是预期的行为。 过滤器不是“表达式感知”的,不会根据它们的lookup_expr
改变行为。
您可以像在第二个示例中那样手动创建过滤器类,也可以使用Meta.fields
的字典样式语法自动生成过滤器。 在内部,它的作用与您的示例相同。
例如,
class MyModelFilter(Filters.FilterSet):
class Meta:
model = MyModel
fields = {
'my_field': ['exact', 'in', ...],
}
嗨@rpkilby
谢谢你的回复。
恕我直言,这在文档中不是很明显,所以也许你可以在文档中添加更多关于它的信息。
此外,由于某种原因,带有Meta.fields
的第二个示例对我不起作用。
@maxtepkeev非常欢迎文档上的任何 PR!
我认为根本问题是 CharFilter 只期望(接收?)单个值,而不是列表; 这来自小部件如何映射来自GET
QueryDict
的数据——所有_that_ 都是 Django Forms 内部结构,这对很多人来说并不是那么清楚。 我们可能需要一些_背景阅读_来解释机制......
@rpkilby是的,很难找到,但我已经阅读了本节,之后我实现了我当前的工作解决方案,即:
from django_filters import filters as df_filters
from rest_framework import filters
from ..models import MyModel
class CharInFilter(df_filters.BaseInFilter, df_filters.CharFilter):
pass
class MyModelFilter(filters.FilterSet):
my_field = CharInFilter()
class Meta:
model = MyModel
Meta.fields
仍然对我不起作用,它不会产生任何回溯、错误或其他任何东西,它只会返回空结果集,这就是我尝试使用它的方式:
from rest_framework import filters
from ..models import MyModel
class MyModelFilter(filters.FilterSet):
class Meta:
model = MyModel
fields = {
'my_field': ['in'],
}
正如我之前所说,我将 django-filter 与 django-rest-framework 一起使用,我在 URL 中使用?my_field=Option1,Option2
语法,该语法正确地适用于我当前的解决方案,但不适用于Meta.fields
.
啊,你应该用?my_field__in=Option1,Option2
过滤。 当您有多个查找时,这更有意义。 例如,
class ProductFilter(filterset.Filter):
class Meta:
model = Product
fields = {'price': ['exact', 'in', 'lt', 'gt'], }
将生成price
、 price__in
、 price__lt
和price__gt
过滤器。
当然,我的错,它现在有效。
但是如果我不喜欢__in
部分,唯一的选择就是像我现在一样使用自定义类,对吧?
是的,如果您对该字段只有一个过滤器,那很好。 但是,如果您对一个字段有多个过滤器,则需要使用一些命名策略来区分它们。 例如, price__in
、 price__lt
、 price__gt
。
是的,这是有道理的。 谢谢。 我没有更多的问题了。
最有用的评论
啊,你应该用
?my_field__in=Option1,Option2
过滤。 当您有多个查找时,这更有意义。 例如,将生成
price
、price__in
、price__lt
和price__gt
过滤器。