当我有相关字段时,如何在Django中执行not in
过滤器?
class Publisher(Model):
pass
class Author(Model):
name = models.CharField(...)
publisher = models.ForeignKey(Publisher)
我可以写:
Publisher.objects.filter(author__name__in=XXX)
这不起作用:
Publisher.objects.filter(author__name__not_in=XXX)
虽然此Django equivalent of SQL not in声明您可以使用exclude
,但这不正确:
Publisher.objects.exclude(author__name__in=XXX)
XXX
是一个名单。
澄清我想要获得的内容:我想找到所有发布者都不在该列表中的作者。注意:这些发布商也可能在该列表中有作者。
我们假设我有两位出版商A,B和以下出版商作者:
A: Alex, Bob, Greg
B: Alex, Greg
xxx是[' Alex',' Greg']
我想找到任何不在该列表中的作者的发布者。在这种情况下,应返回A,因为A的作者Bob不在该列表中。
答案 0 :(得分:0)
看起来Q objects非常适合此查询。
您可以先建立查询参数。
import operator
query = reduce(
lambda x, y: operator.or_(Q(author__name=x), Q(author__name=y)),
XXX
)
# query would be something like Q(author__name='Alex') | Q(author__name='Greg')
Publisher.objects.exclude(query)
使用完全匹配的示例,如果您要在CharField中搜索 ,则必须使用contains
或icontains
。只需使用Q(author__name__icontains=n)
更新Q对象。
答案 1 :(得分:0)
检查exclude()
功能。它是filter()
函数的反函数,但完全符合您的要求。
请注意,您还可以chain functions together:
>>> Entry.objects.filter(
... headline__startswith='What'
... ).exclude(
... pub_date__gte=datetime.date.today()
... ).filter(
... pub_date__gte=datetime(2005, 1, 30)
... )
答案 2 :(得分:0)
什么是XXX
,如果是list
,您应该可以在查询中使用exclude
。
Publisher.objects.exclude(author__name__in=XXX) # Remember XXX must be a list
如果是string
,您应该使用:
Publisher.objects.exclude(author__name__contains=XXX)
如果情况无关紧要:
Publisher.objects.exclude(author__name__icontains=XXX)
答案 3 :(得分:0)
可以使用以下内容:
Publisher.author.filter(author__in=Author.objects.exclude(name__in=xxx))
与潜在巨大的子查询相关的性能成本,特别是在没有很好处理子查询的MySQL上。
另一种方法是实施NOT IN
custom lookup,这是自1.7以来的可能。它看起来像这样:
class NotInLookup(Lookup):
lookup_name = 'not_in'
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return '%s NOT IN (%s)' % (lhs, rhs), params
您必须调查文档,并且可能需要source code of IN
来查找编写此查找的正确方法。可能有兴趣将其添加到核心,因此如果您正常工作,请随时在https://groups.google.com/forum/#!forum/django-developers的邮件列表中将其提升。