这是 De Morgan's law [wiki] 的结果,它指定 ¬ (x ∧ y) 是 ¬ x ∨ ¬ y。因此这意味着 x 和 y 的否定是 not x 或 not y。确实,如果我们看一下真值表:
x |是 | x &楔;是 | ¬x | ¬y | ¬(x ∧ y) | ¬x &ve; ¬y
---+---+-------+----+----+----------+---------
0 | 0 | 0 | 1 | 1 | 1 | 1
0 | 1 | 0 | 1 | 0 | 1 | 1
1 | 0 | 0 | 0 | 1 | 1 | 1
1 | 1 | 1 | 0 | 0 | 0 | 0
所以排除项目两个starthour在(start, end)范围和endhour在(start, end)范围,逻辑上等效于允许starthour不在范围内的项目不,或在endhour不在范围内的项目范围。
使用与逻辑
因此,您可以在 .exclude(…) 调用中进行析取以过滤掉满足两个条件之一的项目,或者保留不满足两个条件中的任何的对象:
MyTable.objects.filter(date=date).exclude(
Q(starthour__range=(start, end)) | Q(endhour__range=(start, end))
)
重叠逻辑
然而,根据您的查询,您正在寻找重叠,而不是此类范围检查。 不够验证starthour 和endhour。如果你想检查两件事是否重叠。事实上,假设一个事件从 08:00 开始到 18:00 结束,并且您过滤了 09:00 和 17:00 的范围,那么 starthour 和 endhour 都不是 em> 在范围内,但事件仍然重叠。
两个范围[s1, e1]和[s2, e2] 如果 s1≥ e2 则 不 重叠,或 s2≥ e1。否定,两者重叠时的条件是:s12 and s21。因此,我们可以排除与以下内容重叠的项目:
# records that do not overlap
MyTable.objects.filter(date=date).exclude(
starthour__lt=end, endhour__lt=start
)