Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.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
Python Django ORM-如何在多对多字段的两个条件下左连接_Python_Django_Django Orm - Fatal编程技术网

Python Django ORM-如何在多对多字段的两个条件下左连接

Python Django ORM-如何在多对多字段的两个条件下左连接,python,django,django-orm,Python,Django,Django Orm,我有两种型号: 类Subscriptionmodels.Model: name=models.CharFieldmax_length=100,unique=True 类模型。模型: email=models.EmailFieldunique=True 订阅=models.ManyToManyFieldSubscription is_confirm=models.BooleanFielddefault=False 我需要通过django orm模拟sql查询 从时事通讯订阅中选择* 左键加入时事通

我有两种型号:

类Subscriptionmodels.Model: name=models.CharFieldmax_length=100,unique=True 类模型。模型: email=models.EmailFieldunique=True 订阅=models.ManyToManyFieldSubscription is_confirm=models.BooleanFielddefault=False 我需要通过django orm模拟sql查询

从时事通讯订阅中选择* 左键加入时事通讯\u邮件\u订阅ms 在ss.id=ms.subscription\u id和ms.mail\u id=; 因此,我可以通过获取可用订阅的完整列表来查看邮件是否订阅了每个订阅

我需要像FilteredRelated这样的东西:

q=Subscription.objects.annotate is_subscribe=FilteredRelation “邮件订阅”,条件=Qmail\u订阅邮件\u id=10
但是FilteredRelation不支持跨关系字段的条件

完全不需要使用FilteredRelation执行此操作,您可以这样编写:

Subscription.objects.filter(
    email__id=mail_id
)
无论如何都不需要使用左外部联接,因为您检查mail_id是否是特定的id,因此内部联接将产生相同的集合

请注意,您使用了ManyToManyField,Django在这两个实体之间创建了一个表,但是您不能访问该表,除非您使用参数指定了一个模型

您还可以使用is_subscribed对订阅进行注释,如:

这将导致一个查询,如:

SELECT subscription.*,
    EXISTS(
        SELECT U0.id, U0.email_id, U0.subscription_id
        FROM email_subscriptions U0
        WHERE U0.subscription_id = subscription.id AND U0.mail_id = email_id
    ) AS is_subscribed
FROM subscription

谢谢你的回答!是的,但我需要获取可能订阅的整个列表,以便指定is_subscribed字段,因此我将使用左连接。我想在is_订阅字段中使用来自左连接的null。谢谢,这对我很有用。存在于SELECT not too long?@pylame22:通常情况下,如果它是一个不错的数据库系统,它会在找到一行后立即被切断。
from django.db.models import Exists, OuterRef

Subscription.objects.annotate(
    is_subscribed=Exists(
        Email.subscriptions.through.objects.filter(
            subscription_id=OuterRef('id'),
            mail_id=email_id
        )
    )
)
SELECT subscription.*,
    EXISTS(
        SELECT U0.id, U0.email_id, U0.subscription_id
        FROM email_subscriptions U0
        WHERE U0.subscription_id = subscription.id AND U0.mail_id = email_id
    ) AS is_subscribed
FROM subscription