Sql 如何获得Django QuerySet';排除';工作正常吗?

Sql 如何获得Django QuerySet';排除';工作正常吗?,sql,django,orm,Sql,Django,Orm,我有一个数据库,其中包含SKU、套件、套件内容和检查表的模式。这里是一个查询“给我为清单1中定义的套件记录定义的kitcontent记录定义的所有SKU”: 我使用的是Django,我非常喜欢ORM,因为我可以通过以下方式表达该查询: skus = SKU.objects.filter(kitcontent__kit__checklist_id=1).distinct() 这是一个如此巧妙的方式来导航所有这些外键。Django的ORM生成的SQL与上面编写的SQL基本相同。问题是我不清楚如何获

我有一个数据库,其中包含SKU、套件、套件内容和检查表的模式。这里是一个查询“给我为清单1中定义的套件记录定义的kitcontent记录定义的所有SKU”:

我使用的是Django,我非常喜欢ORM,因为我可以通过以下方式表达该查询:

skus = SKU.objects.filter(kitcontent__kit__checklist_id=1).distinct()
这是一个如此巧妙的方式来导航所有这些外键。Django的ORM生成的SQL与上面编写的SQL基本相同。问题是我不清楚如何获得清单1中未定义的所有SKU。在上面的SQL查询中,我将用“!=”替换“=”。但Django的模型没有不等于运算符。您应该使用exclude()方法,您可能会猜测该方法如下所示:

skus = SKU.objects.filter().exclude(kitcontent__kit__checklist_id=1).distinct()
但是Django生成了这个查询,它不是一回事:

SELECT distinct s.*  FROM skus s 
WHERE NOT ((skus.id IN 
    (SELECT kc.sku_id FROM kit_contents kc 
    INNER JOIN kits k ON (kc.kit_id = k.id) 
    WHERE (k.checklist_id = 1  AND kc.sku_id IS NOT NULL)) 
AND skus.id IS NOT NULL))
(为了便于阅读和比较,我已经清理了查询。)

我是Django ORM的初学者,如果可能的话,我想使用它。有办法得到我想要的吗

编辑:

karthikr给出了一个不起作用的答案,原因与原始ORM.exclude()解决方案不起作用的原因相同:SKU可以位于checklist_id=1和checklist_id=2上存在的kit_内容中。使用我打开帖子时使用的手动查询,使用“checklist\u id=1”生成34个结果,使用“checklist\u id=2”生成53个结果,以下查询生成26个结果:

SELECT DISTINCT s.* FROM skus s
JOIN kit_contents kc ON kc.sku_id = s.id
JOIN kits k          ON k.id = kc.kit_id
JOIN checklists c    ON k.checklist_id = 1
JOIN kit_contents kc2 ON kc2.sku_id = s.id
JOIN kits k2          ON k2.id = kc2.kit_id
JOIN checklists c2    ON k2.checklist_id = 2;

我认为这就是为什么人们似乎不认为.exclude()解决方案是某种非_equals过滤器的合理替代品的一个原因——后者允许您简明扼要地说出您的确切意思。想必前者也允许表达查询,但我越来越不希望这样的解决方案简单。

您可以这样做-获取清单1的所有对象,并将其从完整列表中排除

sku_ids = skus.values_list('pk', flat=True)
non_checklist_1 = SKU.objects.exclude(pk__in=sku_ids).distinct()

旁注:您不需要额外调用
filter()
,只需执行
SKU.objects.exclude(…)
是否希望所有与清单1无关的SKU,或与清单1以外的SKU相关?或者“清单1未定义”完全是指其他内容吗?与清单1以外的清单相关的所有SKU。困难似乎在于它们可能也与1有关,但我不想知道它们与1有关的意义。我最初的SQL查询中的连接语法表达了这种区别(废话废话连接检查表c,其中k.checklists.id!=1),但我无法排除。请这样做。谢谢您的回答;但请查看我的编辑,了解为什么它不起作用。
sku_ids = skus.values_list('pk', flat=True)
non_checklist_1 = SKU.objects.exclude(pk__in=sku_ids).distinct()