Django通过列表中的值从数据库中查找项目?

Posted

技术标签:

【中文标题】Django通过列表中的值从数据库中查找项目?【英文标题】:Django find items from db by values from list? 【发布时间】:2018-11-24 16:21:24 【问题描述】:

我有一个字符串列表:

phrases_filter = json.loads(request.GET['phrases_filter'])
['xx', 'yy']

我需要在 db 中查找所有包含 xx OR yy

的短语

我试过这样:

Phrase.objects.filter(name__in phrases_filter)

但这只给了我名字中包含 xx AND yy

的短语

【问题讨论】:

【参考方案1】:

我们可以展开列表,并用or-logic定义一组__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(..) 的工作方式类似于 函数式编程 中已知的“折叠”(这是 catamorphism 的一个特例)。

因此,我们将在两者之间添加or_s,从而得到Q(name__contains='xx') | Q(name__contains='yy')。这是一个基本上对过滤条件进行编码的对象:这意味着name 列应该__contains 子字符串'xx',或子字符串'yy'

注意:如果你想匹配大小写敏感(所以行带有XX,或Xx,或xX,或xx所有个候选),然后将__contains替换为__<b>i</b>contains

编辑:根据您的评论,如果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 元素上包含至少的情况下,我们才会执行过滤。

【讨论】:

你能不能逐行解释,我不太明白它是怎么工作的,这是什么意思 这个phrases_filter也可以为空 @user2950593:如果它是空的,那会发生什么?没有匹配,还是所有行都匹配? 所有行匹配=) 好的,似乎正在工作=) 这是完成这项任务的首选方式吗?

以上是关于Django通过列表中的值从数据库中查找项目?的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据值从视图传递到 Django 中的模板?

将值从表单传递到表单

如何使用Java中的给定字符串值从数组列表中查找最长前缀?

VBA代码根据excel工作簿中的值从webform下拉列表中选择一个值

将下拉列表中的值从一个 php 传递到另一个

根据字典中的键值检查列表中的值,Python