Python 如何对多个外键执行exclude django查询

Python 如何对多个外键执行exclude django查询,python,django,Python,Django,我的模型示例: class Thing(models.Model): alpha = models.ForeignKey('auth.User', on_delete=models.CASCADE, related_name='alpha_thing') beta = models.ForeignKey('auth.User', on_delete=models.CASCADE,

我的模型示例:

class Thing(models.Model):

    alpha = models.ForeignKey('auth.User', on_delete=models.CASCADE,
                             related_name='alpha_thing')

    beta = models.ForeignKey('auth.User', on_delete=models.CASCADE,
                               related_name='beta_thing')
    assigned_at = models.DateTimeField(
        _('assigned at'),
        null=True,
        help_text=_('Assigned at this date'))
我希望查询所有在日期没有分配
的东西的用户,即他们可以有其他东西,但应该有一个日期集

我试过:

return User.objects.exclude(
    alpha_thing__assigned_at__isnull=True
).exclude(
    beta_thing__assigned_at__isnull=True
).all()
但是结果是空的(thing表是空的,所以我不确定它是否与join有关?)。

这个呢

from django.db.models import Q

User.objects.filter(Q(alpha_thing__assigned_at__isnull=False) | Q(beta_thing__assigned_at__isnull=False)).distinct()
截图 1。验证模型结构-
用户

2。事物模型

对于所有没有空日期的用户,请尝试:

return User.objects.exclude(
    alpha_thing__assigned_at=None
).exclude(
    beta_thing__assigned_at=None
).all()
顺便说一下,无论是否在结尾使用
.all()
,我都得到了相同的结果,因此:

return User.objects.exclude(
    alpha_thing__assigned_at=None
).exclude(
    beta_thing__assigned_at=None
)

返回与第一个示例相同的结果。

还有另一种方法,因为您希望筛选包含所有
指定日期的用户

你可以:

User.objects.filter(
    alpha_thign__assigned_at__isnull=False,
    beta_thign__assigned_at__isnull=False,
)
简单

这里不需要使用
Q
对象或
|
(或)操作

你想要的不是

  • alpha\u thing\uu assigned\u at\uu\u isnull=False
  • beta\u thing\uu assigned\u at\uu isnull=False
你要找的是

  • alpha\u thing\uu assigned\u at\uu\u isnull=False
  • beta\u thing\uu assigned\u at\uu isnull=False

    • 你试过这样的东西吗

      from django.db.models import Q
      
      has_null_alpha = Q(alpha_thing__isnull=False, alpha_thing__assigned_at__isnull=True)
      
      has_null_beta = Q(beta_thing__isnull=False, beta_thing__assigned_at__isnull=True)
      
      User.objects.exclude(has_null_alpha | has_null_beta)
      
      推理 我认为您看到意外结果的原因可能与queryset中存在多个
      ForeignKey
      路径这一事实无关。您关于“thing table为空”的陈述可能是关键,而用户没有出现的原因是他们没有
      alpha\u thing
      beta\u thing
      关系

      笔记:
      • QuerySet
        User.objects.exclude(alpha\u thing\u assigned\u at\uu isnull=True)
        User
        表和
        thing
        表之间生成一个左外连接,这意味着在
        WHERE
        子句中进行任何比较之前,在没有
        东西的任何行中,您将在
        处为
        赋值
        得到
        NULL

      • 这里一个非常奇怪的事情是,
        filter
        导致一个内部联接,因此语句
        User.objects.filter(alpha\u thing\u assigned\u at\uu isnull=False)
        实际上只生成实际拥有
        alpha\u thing
        相关对象的用户,这些对象的
        赋值为
        assigned\u at
        (不包括那些没有相关信息的人)


      只是想澄清一下:如果我有这些东西的集合[Thing(user1,user2,datetime),Thing(user2,user3,None)]…你想要哪个用户?[user2,user3],[user3]…?@spadarian所有没有空日期的用户,所以你的例子不是user2和user3,所以只需要user1。我想你的意思是“所有在<代码>日期没有
      分配对象的用户”-正确吗?请仔细检查:您想包括
      用户
      对象,这些对象没有任何相关的
      alpha\u对象
      beta\u对象
      对象,对吗?