Django不在相关领域

时间:2015-05-29 20:46:11

标签: django django-queryset django-orm django-filter

当我有相关字段时,如何在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不在该列表中。

4 个答案:

答案 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中搜索 ,则必须使用containsicontains。只需使用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的邮件列表中将其提升。