Django-filter: 在查找

创建于 2016-03-25  ·  9评论  ·  资料来源: carltongibson/django-filter

你好,

我正在使用 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

这是正常和预期的行为,还是我在这里做错了什么? 谢谢。

最有用的评论

啊,你应该用?my_field__in=Option1,Option2过滤。 当您有多个查找时,这更有意义。 例如,

class ProductFilter(filterset.Filter):
    class Meta:
        model = Product
        fields = {'price': ['exact', 'in', 'lt', 'gt'], }

将生成priceprice__inprice__ltprice__gt过滤器。

所有9条评论

嗨@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 内部结构,这对很多人来说并不是那么清楚。 我们可能需要一些_背景阅读_来解释机制......

@carltongibson我今晚晚些时候会尝试解决这个问题。 可以将改写为关于常见问题和/或理论的部分。

@maxtepkeev这是将BaseInFilter与其他过滤器类型混合的文档,但是如何到达那里并不完全清楚。 例如,如果您要搜索有关如何正确使用CharFilterlookup_expr='in'的文档,您可能找不到该部分。
你还在为Meta.fields语法而烦恼吗? 也许发布模型/过滤器代码和回溯?

@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'], }

将生成priceprice__inprice__ltprice__gt过滤器。

当然,我的错,它现在有效。

但是如果我不喜欢__in部分,唯一的选择就是像我现在一样使用自定义类,对吧?

是的,如果您对该字段只有一个过滤器,那很好。 但是,如果您对一个字段有多个过滤器,则需要使用一些命名策略来区分它们。 例如, price__inprice__ltprice__gt

是的,这是有道理的。 谢谢。 我没有更多的问题了。

此页面是否有帮助?
0 / 5 - 0 等级