使用Q对象时排除vs过滤器

时间:2018-03-13 00:45:02

标签: python django

无法理解这是如何可能的:

A = object_list.filter( Q(sales__sale_starts__lte=today) & Q(sales__sale_ends__gte=today) )
# query inside filter catches 2 objects

B = object_list.exclude( Q(sales__sale_starts__lte=today) & Q(sales__sale_ends__gte=today) )
# query inside exclude catches 3 objects,
# though it is the same as previous

# in other words: object_list contains 20 objects,
# A - 2 objects, and B - 17 objects

使用filter()对象时exclude()Q的工作方式有何不同?感谢。

我希望B如下:

B = object_list.difference(A)
# B contains 18 objects

2 个答案:

答案 0 :(得分:1)

正如@PauloAlmeida所说

  

多值结果可能是个问题,请参阅以下两个错误报告:Exclude query with multiple conditions for the same multi-value relation not correct; Problem with negating Q object.

因为不同的sql生成,filter()exclude()之间确实存在差异。也许是exclude()中的错误。

答案 1 :(得分:0)

行为应该是一样的。如果您查看.exclude().filter()源代码,他们会这样做:

def exclude(self, *args, **kwargs):
    """
    Returns a new QuerySet instance with NOT (args) ANDed to the existing
    set.
    """
    return self._filter_or_exclude(True, *args, **kwargs)

def filter(self, *args, **kwargs):
    """
    Returns a new QuerySet instance with the args ANDed to the existing
    set.
    """
    return self._filter_or_exclude(False, *args, **kwargs)

_filter_or_exclude()只会使用Q

取消~过滤器
def _filter_or_exclude(self, negate, *args, **kwargs):
    if args or kwargs:
        assert self.query.can_filter(), \
            "Cannot filter a query once a slice has been taken."

    clone = self._clone()
    if negate:
        clone.query.add_q(~Q(*args, **kwargs))
    else:
        clone.query.add_q(Q(*args, **kwargs))
    return clone