You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中使用ORM实现指定的左连接SQL查询?

用Django ORM实现左连接查询

嘿,我来帮你搞定这个问题!首先得先明确你的Django模型结构,假设你的模型大概是这样的(如果和你的实际情况有出入,调整一下关联字段就行):

from django.db import models
from django.contrib.auth.models import User

class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    # 其他文章相关字段

class Upvote(models.Model):
    article = models.ForeignKey(
        Article, 
        on_delete=models.CASCADE, 
        related_name='upvotes'  # 这个反向关联名很重要,用来从Article关联到Upvote
    )
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

接下来分两种场景给你解决方案:

场景1:获取文章对象及对应的所有点赞记录(面向对象的方式)

这是Django ORM最常用的方式,用prefetch_related来实现反向关联的左连接效果(底层会先查询所有文章,再批量查询对应的点赞记录,然后在Python层面关联,性能也很好):

# 获取所有文章,同时预加载对应的点赞记录
articles = Article.objects.all().prefetch_related('upvotes')

# 遍历使用
for article in articles:
    print(f"文章标题: {article.title}")
    # 获取这篇文章的所有点赞记录
    for upvote in article.upvotes.all():
        print(f"点赞用户: {upvote.user.username}, 点赞时间: {upvote.created_at}")
    # 如果没有点赞记录,article.upvotes.all()会返回空QuerySet

场景2:生成和你SQL完全一致的单条左连接查询(返回扁平结果)

如果你需要的是和原生SQL一样的扁平结果集(每条记录包含文章字段+点赞字段,无点赞则点赞字段为NULL),可以用raw()方法直接执行你的SQL:

# 执行原生SQL查询
results = Article.objects.raw("""
    select * from article_article 
    left join article_upvote 
    ON article_article.id=article_upvote.article_id
""")

# 遍历结果
for row in results:
    # 访问文章字段,比如row.title, row.content
    # 访问点赞字段,比如row.user_id, row.created_at(如果没有点赞,这些字段会是None)
    print(f"文章标题: {row.title}, 点赞用户ID: {row.user_id}")

另外补充一点:如果你不想用原生SQL,也可以用annotate结合Subquery来获取特定的点赞字段,但如果要获取所有点赞字段,原生SQL会更直接。

内容的提问来源于stack exchange,提问作者Kritika Shrivastava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:57:38