python - Django通过列表中的值从数据库中查找项目?
问题描述
我有一个字符串列表:
phrases_filter = json.loads(request.GET['phrases_filter'])
['xx', 'yy']
我需要在 db 中查找所有包含xx
OR的短语 yy
我试过这样:
Phrase.objects.filter(name__in phrases_filter)
但这给了我只有名字xx
和 yy
解决方案
我们可以展开__contains
列表,并使用或逻辑定义一组谓词:
from django.db.models import Q
from functools import reduce
from operator import or_
Phrase.objects.filter(
reduce(or_, (Q(name__contains=e) for e in phrases_filter))
)
在给定的情况下phrases_filter
,我们将生成等效于:
Phrase.objects.filter(
Q(name__contains='xx') | Q(name__contains='yy')
)
所以reduce(..)
将对对象的生成器进行操作Q(..)
,这里[Q(name__contains='xx'), Q(name__contains='yy')]
。这些reduce(..)
作品类似于函数式编程中所谓的“折叠”(这是一种变态现象的特例)。
因此,我们将or_
在两者之间添加 s,从而得到Q(name__contains='xx') | Q(name__contains='yy')
。这是一个基本上对过滤条件进行编码的对象:这意味着该name
列应该__contains
是 substring'xx'
或 substring 'yy'
。
注意:如果您想在敏感的情况下匹配大小写(因此带有
XX
, orXx
, orxX
, or的行都是xx
候选者),然后替换为.__contains
__icontains
编辑:根据您的评论,如果phrases_filter
为空,您希望所有行都匹配,我们可以使用以下if
语句来做到这一点:
from django.db.models import Q
from functools import reduce
from operator import or_
queryset = Phrase.objects.all()
if phrases_filter:
queryset = filter(
reduce(or_, (Q(name__contains=e) for e in phrases_filter))
)
因此,只有在至少phrases_filter
包含一个元素的情况下,我们才会执行过滤。
推荐阅读
- reactjs - 将 useReducer 与数组解构结合使用时出现类型错误
- java - CountDownTimer 不会被重置
- python - 在 python 中解码 utf-8
- docker - 使用 VSCode 开发容器设置 Docker 中的 Docker:如何访问主机上正在运行的 docker 容器
- excel - 使用 Selenium Excel VBA for chrome 单击网页上的按钮
- java - 打开 swagger UI 给 404 和 Micronaut
- c++ - 要在 CMakeLists 文件中写入的命令
- java - 线程安全的类和对象
- react-native - React Native - 从内置组件获取未定义的返回值错误
- javascript - 为什么下面的 react 功能组件不能正常工作?