如何在Django中保留额外条件的外部联接

编程入门 行业动态 更新时间:2024-10-23 13:23:33
本文介绍了如何在Django中保留额外条件的外部联接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有这三个模型:

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 时得到的:

And I want to retrieve all Tracks that are not tagged with a specific tag. This gets me what I want: Track.objects.exclude(trackhastag__tag_id='1').only('id') but it's very slow when the tables grow. This is what I get when printing .query of the queryset:

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发送此查询而是:

I would like Django to send this query instead:

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;

但是还没有找到一种方法。使用原始查询并不是真正的选择,因为我不得不非常频繁地过滤结果查询集。

But haven't found a way to do so. Using a Raw Query is not really an option as I have to filter the resulting queryset very often.

我发现的最干净的解决方法是在数据库中创建一个视图,然后我用来查询的模型 TrackHasTagFoo 具有 managed = False 的模型,例如: Track.objects。 filter(trackhastagfoo__isnull = True)。我不认为这是一个优雅且不可持续的解决方案,因为它涉及在我的迁移中添加Raw SQL来维持上述观点。

The cleanest workaround I have found is to create a view in the database and a model TrackHasTagFoo with managed = False that I use to query like: Track.objects.filter(trackhastagfoo__isnull=True). I don't think this is an elegant nor sustainable solution as it involves adding Raw SQL to my migrations to mantain said view.

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

This is just one example of a situation where we need to do this kind of left join with an extra condition, but the truth is that we are facing this problem in more parts of our application.

非常感谢!

推荐答案

如 Django#29555 ,您可以为此目的使用 FilteredRelation 自Django 2.0起。

As mentioned in Django #29555 you can use FilteredRelation for this purpose since Django 2.0.

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

更多推荐

如何在Django中保留额外条件的外部联接

本文发布于:2023-10-23 02:04:09,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1519414.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:条件   如何在   Django

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!