如何链接 Django 的“in”和“iexact”查询集字段查找?
Posted
技术标签:
【中文标题】如何链接 Django 的“in”和“iexact”查询集字段查找?【英文标题】:How can I chain Django's "in" and "iexact" queryset field lookups? 【发布时间】:2013-02-01 04:26:25 【问题描述】:我有一个名字列表,例如:
name_list = ['Alpha', 'bEtA', 'omegA']
目前我有以下查询集:
MyModel.objects.filter(name__in=name_list)
我希望能够以不区分大小写的方式过滤名称。我的第一个想法是使用iexact
字段查找,但它似乎不适用于in
。如何将iexact
与in
字段查找一起用于我的查询集?或者是否有其他方法来执行此查询?
【问题讨论】:
in
不能不区分大小写,您必须遍历每个项目执行 iexact
并使用 Q
对象进行组合。
【参考方案1】:
这是一个使用列表推导的示例。它类似于 catherine 的 answer,但有一个数据库命中,如 Derek Kwok 的 answer(但程序性而不是功能性)。
q_list = Q()
for q in [Q(name__iexact=n) for n in name_list]:
q_list |= q
MyModel.objects.filter(q_list)
对于那些喜欢在 Python 中避免使用 zip、map、reduce 等的人。
【讨论】:
【参考方案2】:这是我的解决方案,它使用 Q objects 代替:
name_list = ['Alpha', 'bEtA', 'omegA']
q_list = map(lambda n: Q(name__iexact=n), name_list)
q_list = reduce(lambda a, b: a | b, q_list)
MyModel.objects.filter(q_list)
【讨论】:
+1 干得好,这也很好。我将使用它以供将来参考 我认为 Derek 的回答非常好,但我想知道是否可以从 django 1.7 编写自定义查找来实现相同的目的? docs.djangoproject.com/en/1.7/howto/custom-lookups 请注意:在 python 3 中,您需要从functools
导入 reduce
,因为它不再是关键字。
我创建了一个辅助函数来包装此模式以供重复使用:pastebin.com/raw/cBH8UNz5。你可以这样称呼它query_in_iexact(MyModel.objects, name_list, 'name')
@nhinkle 这是MyModel.objects.filter(Q(name__iexact='Alpha') | Q(name__iexact='bEtA') | ...)
的另一种拼写方式。【参考方案3】:
name_list = ['Alpha', 'bEtA', 'omegA']
results = MyModel.objects.none()
for name in name_list:
results |= MyModel.objects.filter(name__iexact=name)
好的,我测试了它,它可以工作:)
【讨论】:
contains
与 exact
匹配不同。
@Rohan 它是“图标包含”而不是“包含”。如果您仔细阅读 Django 文档,那么您就会知道 contains 和 icontains 之间的区别。
是的,你是对的@cathy,但exact
给出了完全匹配但contains
给出了如果对象与给定查询中的任何字母匹配的结果,在这种情况下我们可能会得到不需要的结果:)跨度>
@kartheek 是的,我知道其中的区别,但你不明白。他说“不精确”而不是“精确”。它们有不同的功能。阅读这个:docs.djangoproject.com/en/dev/topics/db/queries
我生气的是他因为不正确的理由投了我的票。为什么他说“包含”和“精确”。上面的问题是关于“iexact”而不是“exact”。它们不一样。我只是给出了另一个不区分大小写的函数示例。以上是关于如何链接 Django 的“in”和“iexact”查询集字段查找?的主要内容,如果未能解决你的问题,请参考以下文章
python测试开发django-171.ORM查询之exact和iexact
Django 2.0 - iexact 转换为 LIKE 而不是 ILIKE