我的模型结构如下所示:
class OneModel(model):
not_important = IntegerField()
class RelatedModel():
propertyA = IntegerField()
propertyB = IntegerField()
original = ForeignKey(OneModel, related_name='related')
我正在寻找一个原生的django解决方案(没有原始的sql),基本上重新创建这个查询:
select * from OneModel om where not exists
(select id from RelatedModel rm where original_id = om.id and propertyA = 1 and propertyB = 2);
以下是我尝试的内容:
OneModel.objects.exclude(related__propertyA=1, related__propertyB=2)
不幸的是,这会产生选择OneModel
对象的效果,这些对象 与propertyA=1
,或相关的对象与{{1}相关不是那些没有匹配两个标准的单一相关的人。
这是我的django查询中生成的sql:
propertyB=2
为了清楚起见,我的问题不在于使用SELECT lots_of_fields
FROM "OneModel"
WHERE NOT ("OneModel"."id" IN (SELECT U1."original_id" AS Col1
FROM "RelatedModel" U1
WHERE U1."PropertyA" = 1)
AND
"OneModel"."id" IN (SELECT U1."original_id" AS Col1
FROM "RelatedModel" U1
WHERE U1."PropertyB" = 2))
而不是存在,而是使用查询的逻辑。
我尝试过使用Q-objects,但无法找出解决此问题的方法。我也看过F-objects,但它们似乎也不相关。有没有办法在纯django中表达这个,或者我是否有决心编写SQL?
至于为什么不只是使用SQL,我承认它更多只是因为骄傲/想要学习新东西而不是其他任何东西。
答案 0 :(得分:2)
这实际上涵盖在文档中 - 它只是有点难以找到。
Here是链接:向下滚动一点到绿色 “注意”部分。
它基本上说基于外键排除有点不直观,你不能在一个查询中做到这一点。相反,这应该工作(我只是将他们的代码移植到你的名字:
query = OneModel.objects.exclude(
related__in=RelatedModel.objects.filter(
propertyA=1,
propertyB=2,
),
)
Django优化了这一点,尽管看起来好像发生了两次查询,但实际上只有一次调用DB。如果您感到好奇,可以通过query.query
检查SQL调用。