【发布时间】:2011-06-17 00:31:19
【问题描述】:
我需要执行一个 django 查询来检查一个字段是否包含列表中的所有值。该列表将具有不同的长度
例子
User.objects.filter(first_name__contains=['x','y','z'])
【问题讨论】:
标签: django django-models
我需要执行一个 django 查询来检查一个字段是否包含列表中的所有值。该列表将具有不同的长度
例子
User.objects.filter(first_name__contains=['x','y','z'])
【问题讨论】:
标签: django django-models
import operator
from django.db.models import Q
User.objects.filter(reduce(operator.and_, (Q(first_name__contains=x) for x in ['x', 'y', 'z'])))
对于python 3
from functools import reduce
.
【讨论】:
User.objects.filter(reduce(...)) 他正在做相当于User.objects.filter(Q(first_name__contains='x') & Q(first_name__contains='y') & Q(first_name__contains='z'))
first_name 替换为每次迭代都会更改的变量(first_name、last_name 等) 同时保留 __contains?现在,我可以看到对多个字段运行它的唯一方法是重复整个函数并硬编码不同的字段名称。
import operator
from django.db.models import Q
q = ['x', 'y', 'z']
query = reduce(operator.and_, (Q(first_name__contains = item) for item in q))
result = User.objects.filter(query)
【讨论】:
import functools 和 functools.reduce。见this
from django.db.models import Q
User.objects.filter(Q(first_name__contains=x)&Q(first_name__contains=y)&Q(first_name__contains=z))
在 Django 1.8 python 2.7 上为我工作
doc => https://docs.djangoproject.com/en/1.8/ref/models/querysets/#q-objects
最新的 => https://docs.djangoproject.com/en/2.1/ref/models/querysets/#q-objects
【讨论】:
接受的解决方案对我不起作用,但确实如此:
list = ['x', 'y', 'z']
results = User.objects.filter(first_name__contains=list[0])
del list[0]
for l in list:
results = results.filter(first_name__contains=l)
第一个结果变量将存储所有具有 first_name 名称字段值为“x”的对象的列表。
然后在 for 循环中,在第一个过滤结果中过滤“y”。现在您有了一个 QuerySet,它应该包含一个可以找到 'x' 和 'y' 的项目列表。现在,在您过滤任何包含“z”的项目中。
这应该适用于任何长度的列表。
【讨论】:
这在 django 2.2、python 3.8 中对我有用,使用 lambda 而不是“运算符”。 关于 lambda 的解释可以在这里找到:https://www.python-course.eu/lambda.php
from functools import reduce
from django.db.models import Q
my_list = ['x','y','z']
User.objects.filter(reduce(lambda x, y: x & y, [Q(first_name__contains= i for i in my_list]))
【讨论】:
只是另一种方法。
qs = User.objects.all()
for search_term in ('x', 'y', 'z'):
qs = qs.filter(first_name__contains=search_term)
我不确定它是否更好,但它更具可读性。
注意:查询集是惰性的,因此此代码进行 1 个 DB 查询。
【讨论】:
AND (&) 查询。对于OR (|) 查询,必须使用Q 对象。
Qs 更简洁和可读性更强。它非常适合 op 的问题。
这里并不完全适用,但是,如果您有 ManyToManyField 并且您想检查它是否包含特定值,请检查此 https://www.revsys.com/tidbits/tips-using-djangos-manytomanyfield/。
我有一个“产品”和 Django 原生“用户”模型。我的“产品”模型有一个多对多字段users 指向“用户”。然后,我想检查这个类似列表的字段是否包含登录用户。我是通过...users__username_icontains=request.user.username... 完成的,上面的链接帮助我更好地理解什么是多对多字段以及它是如何工作的。
【讨论】:
the_list= []
data_list= ['x', 'y', 'z']
for i in data_list:
a = User.objects.filter(first_name__contains=project).values('etc')
the_list+= a
【讨论】: