Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
django ORM将相关表上的两个条件转换为两个单独的联接_Django_Join_Django Orm - Fatal编程技术网

django ORM将相关表上的两个条件转换为两个单独的联接

django ORM将相关表上的两个条件转换为两个单独的联接,django,join,django-orm,Django,Join,Django Orm,我需要从相关表中筛选两个属性 class Item(models.Model): vouchers = models.ManyToManyField() class Voucher(models.Model): is_active = models.BooleanField() status = models.PositiveIntegerField() 当我像这样查询ORM时: Item.objects.exclude( vouchers__is_a

我需要从相关表中筛选两个属性

class Item(models.Model):
     vouchers = models.ManyToManyField()


class Voucher(models.Model):
     is_active = models.BooleanField()
     status = models.PositiveIntegerField()
当我像这样查询ORM时:

Item.objects.exclude(
    vouchers__is_active=False, 
    vouchers__status__in=[1, 2])      
SELECT *
FROM `item`
WHERE NOT (`item`.`id` IN (
   SELECT U1.`item_id`
   FROM `itemvouchers` U1
   INNER JOIN `voucher` U2 ON (U1.`voucher_id` = U2.`id`)
   WHERE U2.`is_active` = FALSE) 
 AND 
`item`.`id` IN (
   SELECT U1.`item_id`
   FROM `itemvouchers` U1
   INNER JOIN `voucher` U2 ON (U1.`voucher_id` = U2.`id`)
   WHERE U2.`status` IN (1, 2))
)
创建的查询如下所示:

Item.objects.exclude(
    vouchers__is_active=False, 
    vouchers__status__in=[1, 2])      
SELECT *
FROM `item`
WHERE NOT (`item`.`id` IN (
   SELECT U1.`item_id`
   FROM `itemvouchers` U1
   INNER JOIN `voucher` U2 ON (U1.`voucher_id` = U2.`id`)
   WHERE U2.`is_active` = FALSE) 
 AND 
`item`.`id` IN (
   SELECT U1.`item_id`
   FROM `itemvouchers` U1
   INNER JOIN `voucher` U2 ON (U1.`voucher_id` = U2.`id`)
   WHERE U2.`status` IN (1, 2))
)
我想排除处于非活动状态且状态为1或2的凭证

查询所做的是创建两个单独的联接。这在一开始是不必要的,并且对性能有害。其次,这是错误的。

案例:

如果我有一个与
凭证a
凭证b
相关的项目,则找不到它,因为它在联接1中,但不在联接2中

这看起来像是django中的一个bug,但我在web上找不到任何对这个主题有用的东西

我们正在使用
django==2.1.1
并尝试使用
filter
Q
-表达式切换
exclude
。到目前为止,一切都没起作用

谢谢


Ron

您的设置是一个m2m关系,并且您希望排除至少有一个m2m关系的任何单个对象,对于该关系和条件组合为真

M2M关系在筛选/排除查询集时非常特殊,请参阅

在该文件中还应注意:

如上所述,对于跨越多值关系的查询,filter()的行为对于exclude()不是等效实现的。相反,单个exclude()调用中的条件不一定引用同一项

文档中提供的解决方案如下:

Blog.objects.exclude(
    entry__in=Entry.objects.filter(
        headline__contains='Lennon',
        pub_date__year=2008,
    ),
)

不,这不是一个错误。由于
.filter(…)
是存在量化的,
.exists(…)
应该是*普遍量化的,因此行为是这样的。对不起,我没有理解你的意思。请你详细说明一下好吗。此外:你有解决方案吗?