无时F()表达式不适用于外键比较

时间:2019-07-19 15:42:22

标签: django django-models django-queryset

我正在尝试通过F()表达式比较联接中的外键。我构建的QuerySet返回预期结果,除非ForeignKey的值之一为None。

我正在编写一个简单的PTO请求系统。所有PTORequest都有一个配置文件(接受请求的人)和一个批准者(在创建时分配,该任务负责批准请求的人)。所有配置文件都有一个向其报告的“经理”。我的目标是查询所有批准人不是个人档案管理人的PTORequest。

class PTORequest(models.Model):
    profile = models.ForeignKey(Profile, null=True, on_delete=models.SET_NULL, related_name='pto_requests')
    approver = models.ForeignKey(Profile, null=True, on_delete=models.SET_NULL, related_name='employee_pto_requests')

class Profile(models.Model):
    manager = models.ForeignKey('self', null=True, on_delete=models.SET_NULL, related_name="reports") 

我的查询是:

PTORequest.objects.exclude(approver=F("profile__manager"))

它应该足够简单,但是结果令人困惑。

>>>pto = PTORequest.create(profile=profile_1, approver=profile_2)
>>>profile_1.manager = profile_3
>>>profile_1.save()
>>>PTORequest.objects.exclude(approver=F("profile__manager")) # returns 'pto', as expected
<QuerySet [<PTORequest: 1>]>
>>>profile_1.manager = None
>>>profile_1.save()
>>>PTORequest.objects.exclude(approver=F("profile__manager")) # returns empty queryset, unexpected
<QuerySet []>

在将管理器设置为“无”并且PTORequest的批准者设置为profile_3时,管理器与批准者不同,但不会在查询集中返回。我对F()表达式或外键有误解吗?

1 个答案:

答案 0 :(得分:0)

发生的事情是,approverNone,而profile__managerNone,因为您已经删除了该关系。那么排除条件为True,这就是查询集值为[ ]的原因。

如果您不想排除None外键,则可以执行以下操作: .exclude(approver__isnull=False, F("profile__manager"))