Django ORM:排除不 return 预期结果

Django ORM: exclude does not return expected result

Django 1.11.4

我只想 select 只显示丢失物品的相框。 如果物品丢失,lost_day 不为空。

问题:我无法理解 "Wrong result" 的情况。我会说,它应该 return 与 "Correct result" 相同的结果。你能帮我看看它有什么问题吗?

错误结果

>>> Frame.objects.all().exclude(item__lost_day__isnull=True)
    <QuerySet [<Frame: 3>]>

正确结果:

>>> Frame.objects.all().filter(item__lost_day__isnull=False)
    <QuerySet [<Frame: 1>, <Frame: 3>]>

自检

>>> a = Item.objects.get(pk=1)
>>> a.lost_day
datetime.date(1997, 1, 1)
>>> a.lost_day is None
False

>>> b = Item.objects.get(pk=2)
>>> b.lost_day
datetime.date(1997, 2, 2)
>>> b.lost_day is None
False

models.py

class Frame(models.Model):
    pass

class Item(models.Model):
    frame = models.ForeignKey(Frame,
                          blank=False,
                          on_delete=models.PROTECT,
                          verbose_name=_("frame"))
    lost_day = models.DateField(auto_now=False,
                                auto_now_add=False,
                                blank=True,
                                null=True,
                                verbose_name=_("lost"))

你能显示:

Frame.objects.filter(pk=1).values('item__lost_day')

看起来你有多个空引用而不是 lost_day,所以我们有

[{'item__lost_day': None},
 {'item__lost_day': datetime.date(1997, 1, 1)},
 {'item__lost_day': None}]

当您查询 Frame.objects.exclude(item__lost_day__isnull=True) 时,djanqo 会得到所有 frames 没有 item__lost_day__isnull 的帧 pk=3 它有空值,但没有 frame <1>

当你 Frame.objects.filter(item__lost_day__isnull=False) 然后 django 找到所有 frames 不为空 lost_day 并且它们是 1 和 3 == 没问题。

你研究中最麻烦的是你把条件(null, not_null)和方法(filter, exclude)都改了一起.