Django:查询使用包含列表中的每个值

neo*_*ser 42 django django-models

我需要执行一个django查询,检查字段是否包含列表中的所有值.该清单的长度各不相同

User.objects.filter(first_name__contains=['x','y','z'])
Run Code Online (Sandbox Code Playgroud)

Ign*_*ams 67

User.objects.filter(reduce(operator.and_, (Q(first_name__contains=x) for x in ['x', 'y', 'z']))
Run Code Online (Sandbox Code Playgroud)

  • `User.objects.filter(reduce(...))`他做的相当于`User.objects.filter(Q(first_name__contains ='x')&Q(first_name__contains ='y')&Q(first_name__contains = 'Z'))` (11认同)
  • @ IgnacioVazquez-Abrams如果你想在for循环中使用它,有没有办法用一个在每次迭代时改变的变量(`first_name`,`last_name`等)替换`first_name`*同时保持*__contains` ?现在,我可以看到针对多个字段运行此操作的唯一方法是重复整个函数并硬编码不同的字段名称. (2认同)
  • 这行代码非常珍贵,但缺乏任何解释使得这成为一个糟糕的答案。 (2认同)

小智 27

import operator
from django.db.models import Q

q = ['x', 'y', 'z']
query = reduce(operator.and_, (Q(first_name__contains = item) for item in ['x', 'y', 'z']))
result = User.objects.filter(query)
Run Code Online (Sandbox Code Playgroud)

  • @Patrice可能会对所选答案做出相同的评论,由拥有339K代表的人做出.这个答案至少有更多的背景.:) (13认同)
  • 如果使用Python 3,请使用`import functools`并使用`functools.reduce`.见[this](/sf/answers/715849501/) (5认同)
  • 嘿:).欢迎来到SO.介意给你的答案添加一些肉?我们通常希望提供比简单的代码转储更多的信息来获得答案,只是为了帮助其他用户更好地了解正在发生的事情:).谢谢^^ (4认同)

Mar*_*hyn 5

更具可读性的解决方案。

qs = User.objects.all()
for search_term in ('x', 'y', 'z'):
    qs = qs.filter(first_name__contains=search_term) 
Run Code Online (Sandbox Code Playgroud)

注意:查询集是惰性的,因此此代码进行 1 个数据库查询。

  • 是的,这对于“AND”(“&”)查询非常有效。对于“OR”(“|”)查询,必须使用“Q”对象。 (3认同)