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对象
对象,对吗?