无法理解这是如何可能的:
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
答案 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