在官方Django文档中,有关从查询集(https://docs.djangoproject.com/en/dev/ref/models/querysets/#exclude)中排除的部分,有几个查询的解释:
此示例排除pub_date晚于2005-1-3并且标题为“Hello”的所有条目:
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
在SQL术语中,评估为:
SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')
此示例排除pub_date晚于2005-1-3或其标题为“Hello”的所有条目:
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')
在SQL术语中,评估为:
SELECT ...
WHERE NOT pub_date > '2005-1-3'
AND NOT headline = 'Hello'
注意第二个例子更具限制性。
最后一个对我来说并不清楚。我看不出第一个和第二个之间的区别,有人可以解释一下吗?
答案 0 :(得分:2)
第一个示例创建一个嵌套的子表达式,而第二个示例创建两个单独的表达式。
答案 1 :(得分:1)
如果你的意思是“注意第二个例子更具限制性”,那么或许更多数学方法可以帮助你:
NOT (pub_date > '2005-1-3' AND headline = 'Hello')
可以翻译成:
NOT pub_date > '2005-1-3' OR NOT headline = 'Hello'
与之相比:
NOT pub_date > '2005-1-3' AND NOT headline = 'Hello'
限制性较小,因为您希望OR
的任何一部分为真,即A OR B
的限制性低于A AND B
。
回到文档,在第一种情况下,您可以排除那些同时适合这两种限制的人。虽然在第二个中你排除那些符合第一个限制的人,然后排除那些符合第二个限制的人,即 - 你排除那些符合其中一个限制的人。
@OP的评论:想象一下,我们有四个项目AA,AB,BB和CC。如果我们说:
Item.objects.filter(name_startswith='A', name_endswith='B')
结果将是{AB}。当然,如果我们说:
Item.objects.exclude(name_startswith='A', name_endswith='B')
结果将是{AA,BB,CC},因为我们只想排除那些以'A'开头且以'B'结尾的人。下一个:
Item.objects.exclude(name_startswith='A')
将导致{BB,CC}。但是,当我们链时,另一个排除:
Item.objects.exclude(name_startswith='A').exclude(name_endswith='B')
我们实际上在说THE_RESULT_OF_THE_FIRST_EXCLUDE.exclude(name_endswith='B')
。那就是:
{BB, CC}.exclude(name_endswith='B')
将返回{CC}。与filter
不同,
Item.objects.filter(<condition_1>).filter(<condition_2>)
与以下结果相同:
Item.objects.filter(<condition_1>, <condition_2>)
排除链接。它类似于布尔运算:
NOT(A和B)=不是A或不是B. NOT(A或B)=不是A而不是B