如何在同一字段的 Q() 上实现 AND 查找。
class Foo(models.Model):
name = models.ManyToManyField(Type)
class Type(models.Model):
type = models.CharField()
我试过:
Foo.objects.filter(Q(name__type='any'), Q(name__type='some'))
和
Foo.objects.filter(Q(name__type='any') & Q(name__type='some'))
但是它们都提供空查询集。
我知道,这会起作用:
Foo.objects.filter(name__type='any').filter(name__type='some')
然而,当创建更复杂的查询时,Q1
、Q2
、Q3
是 Q()
对象,然后
Foo.objects.filter(Q1).filter(Q2).filter(Q3)
可能会产生与
不同的结果
Foo.objects.filter(Q2).filter(Q3).filter(Q1)
由于过滤器的应用顺序。
更新:我意识到这个 AND 查询有效,因为 modelField 不是 ManyToMany
而是 CharField
:
Type.objects.filter(Q(type__icontains='some') & Q(type__icontains='thing'))
因此仅进行 AND 查询不适用于 ManyToMany 关系。
过滤器
已经是一个AND 查找。通常您会希望使用Q()
查询来组合OR 查找。我这么说是因为使用 AND 查找还有其他方法可以组成动态查询。
预计以下查询将返回一个空查询集:
Foo.objects.filter(Q(name__type='any') & Q(name__type='some'))
因为 Type
实例被命名为“any”或“some”——它不能同时被命名,所以查询集总是空的。
但是语法是正确的。您可以使用它来连接多个 AND 查找表达式(只要它们过滤不同的字段,否则您可能会得到一个空的查询集)。因为过滤器应用于数据库中的每一行。
另一种创建复杂和动态过滤器(使用AND 查找)的方法是使用字典:
params = {
'first_name': 'foo',
'last_name': 'bar'
}
if condition:
params['email'] = 'foo@bar.com'
Foo.objects.filter(**params)
我是一名优秀的程序员,十分优秀!