gpt4 book ai didi

django - 如何在 Django 中使用额外条件离开外部连接

转载 作者:行者123 更新时间:2023-12-04 02:14:13 25 4
gpt4 key购买 nike

我有这三个模型:

class Track(models.Model):
title = models.TextField()
artist = models.TextField()

class Tag(models.Model):
name = models.CharField(max_length=50)

class TrackHasTag(models.Model):
track = models.ForeignKey('Track', on_delete=models.CASCADE)
tag = models.ForeignKey('Tag', on_delete=models.PROTECT)

我想检索所有没有用特定标签标记的轨道。这让我得到了我想要的: Track.objects.exclude(trackhastag__tag_id='1').only('id')但是当表增长时它很慢。这是我打印时得到的 .query查询集的:
SELECT "track"."id" 
FROM "track"
WHERE NOT ( "track"."id" IN (SELECT U1."track_id" AS Col1
FROM "trackhastag" U1
WHERE U1."tag_id" = 1) )

我希望 Django 改为发送此查询:
SELECT "track"."id" 
FROM "track"
LEFT OUTER JOIN "trackhastag"
ON "track"."id" = "trackhastag"."track_id"
AND "trackhastag"."tag_id" = 1
WHERE "trackhastag"."id" IS NULL;

但是还没有找到办法。使用原始查询并不是一个真正的选择,因为我必须经常过滤结果查询集。

我发现的最干净的解决方法是在数据库中创建一个 View 和一个模型 TrackHasTagFoomanaged = False我用来查询: Track.objects.filter(trackhastagfoo__isnull=True) .我认为这不是一个优雅且可持续的解决方案,因为它涉及将原始 SQL 添加到我的迁移中以维护所述 View 。

这只是我们需要使用额外条件进行这种左连接的情况的一个示例,但事实是我们在应用程序的更多部分都面临这个问题。

非常感谢!

最佳答案

Django #29555 中所述您可以使用 FilteredRelation为此目的since Django 2.0 .

Track.objects.annotate(
has_tag=FilteredRelation(
'trackhastag', condition=Q(trackhastag__tag=1)
),
).filter(
has_tag__isnull=True,
)

关于django - 如何在 Django 中使用额外条件离开外部连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51175110/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com