gpt4 book ai didi

python - 带 DRF 的 Django 过滤器 - 在使用相同查找应用多个值时如何处理 'and'?

转载 作者:行者123 更新时间:2023-11-28 21:07:37 41 4
gpt4 key购买 nike

这是我使用的过滤器集的一个稍微简化的示例,我将其与 Django Rest Framework 的 DjangoFilterBackend 一起使用。我希望能够向 /api/bookmarks/?title__contains=word1&title__contains=word2 发送请求,并返回包含这两个词的结果,但目前它忽略第一个参数,只过滤词2。

如有任何帮助,我们将不胜感激!

class BookmarkFilter(django_filters.FilterSet):

class Meta:
model = Bookmark
fields = {
'title': ['startswith', 'endswith', 'contains', 'exact', 'istartswith', 'iendswith', 'icontains', 'iexact'],
}

class BookmarkViewSet(viewsets.ModelViewSet):
serializer_class = BookmarkSerializer
permission_classes = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend,)
filter_class = BookmarkFilter
ordering_fields = ('title', 'date', 'modified')
ordering = '-modified'
page_size = 10

最佳答案

主要问题是您需要一个了解如何对多个值进行操作的过滤器。基本上有两种选择:

  • 使用 MultipleChoiceFilter(不推荐用于此实例)
  • 编写自定义过滤器类

使用MultipleChoiceFilter

class BookmarkFilter(django_filters.FilterSet):
title__contains = django_filters.MultipleChoiceFilter(
name='title',
lookup_expr='contains',
conjoined=True, # uses AND instead of OR
choices=[???],
)

class Meta:
...

虽然这保留了您想要的语法,但问题是您必须构建一个选择列表。我不确定您是否可以简化/减少可能的选择,但看起来您似乎需要从数据库中获取所有标题,将标题拆分为不同的单词,然后创建一个集合以删除重复项。根据您拥有的记录数量,这似乎会很昂贵/很慢。

自定义过滤器

或者,您可以创建自定义过滤器类 - 如下所示:

class MultiValueCharFilter(filters.BaseCSVFilter, filters.CharFilter):
def filter(self, qs, value):
# value is either a list or an 'empty' value
values = value or []

for value in values:
qs = super(MultiValueCharFilter, self).filter(qs, value)

return qs


class BookmarkFilter(django_filters.FilterSet):
title__contains = MultiValueCharFilter(name='title', lookup_expr='contains')

class Meta:
...

用法(注意值是用逗号分隔的):

GET /api/bookmarks/?title__contains=word1,word2

结果:

qs.filter(title__contains='word1').filter(title__contains='word2')

语法略有改变,但基于 CSV 的过滤器不需要构建不必要的选择集。

请注意,实际上不可能支持 ?title__contains=word1&title__contains=word2 语法,因为小部件无法呈现合适的 html 输入。您需要使用 SelectMultiple(同样需要选择),或者在客户端使用 javascript 添加/删除具有相同 name 属性的其他文本输入。


无需赘述,过滤器和过滤器集只是 Django 表单的扩展。

  • 一个 Filter 有一个表单 Field,它又有一个 Widget
  • FilterSetFilter 组成。
  • FilterSet 根据其过滤器的字段生成内部表单。

每个过滤器组件的职责:

  • 小部件从数据 中检索原始值QueryDict .
  • 该字段验证原始值。
  • 过滤器使用经过验证的值构造对查询集的 filter() 调用。

为了对同一个过滤器应用多个值,您需要一个了解如何对多个值进行操作的过滤器、字段和小部件。


自定义过滤器通过混合 BaseCSVFilter 实现这一点,后者又将“逗号分隔 => 列表”功能混合到组合字段和小部件类中。

我建议查看 CSV 混合宏的源代码,简而言之:

  • widget将传入值拆分为值列表。
  • field通过验证“主”字段类(例如 CharFieldIntegerField)上的各个值来验证整个值列表。该字段还派生了混合的小部件。
  • filter简单地派生混合字段类。

CSV 过滤器旨在与 inrange 查找一起使用,它们接受值列表。在这种情况下,contains 需要一个值。 filter() 方法通过遍历值并将各个过滤器调用链接在一起来解决此问题。

关于python - 带 DRF 的 Django 过滤器 - 在使用相同查找应用多个值时如何处理 'and'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41194200/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com