【问题标题】:How to build SQL query with two left joins using django ORM如何使用 django ORM 构建带有两个左连接的 SQL 查询
【发布时间】:2012-02-10 11:40:48
【问题描述】:

我需要构建一个 MySQL 查询,我想先尝试使用 django ORM,然后将 raw 作为最后的手段。

我找到了关于两个表之间的单个 JOIN 或 JOIN 的文档,但是没有示例,或者至少是对三个表之间的 JOIN 的简单(初学者)解释

models.py 的内容是

from django.db import models

# Create your models here.
class Threads(models.Model):
    name = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    date = models.DateTimeField("date published")
    slug = models.SlugField()

    def __unicode__(self):
        return self.name

class Posts(models.Model):
    name = models.CharField(max_length=100)
    text = models.TextField()
    author = models.CharField(max_length=100)
    date = models.DateTimeField("date published")
    slug = models.SlugField()

    def __unicode__(self):
        return self.name

class Relations(models.Model):
    thread = models.ForeignKey(Threads, related_name = "%(app_label)s_%(class)s_related")
    post = models.ForeignKey(Posts, related_name = "%(app_label)s_%(class)s_related")

这是我正在尝试构建的原始 SQL 查询

SELECT forum_threads.id AS t_id, forum_threads.name AS t_name, forum_threads.slug AS t_slug, forum_posts.*
FROM forum_threads
LEFT JOIN forum_relations ON forum_threads.id=forum_relations.thread_id
LEFT JOIN forum_posts ON forum_relations.post_id=forum_posts.id
WHERE forum_threads.slug="<slug_name>"
GROUP BY forum_threads.id

“论坛”是我的应用名称

现在我不知道我是否需要调整/更改我的模型,以及是否需要如何调整。请注意,我不能更改任何重要数据的模型。

编辑

感谢您的所有回答!

好吧,我玩了一些不同的例子,直到我设法产生了一些东西。我是这样理解的:

thread = Threads.objects.filter(slug = slug)

posts = Posts.objects.filter(forum_relations_related__thread = thread[0].id)

第一个查询是从 slug 中检索线程 id,第二个查询返回与该线程 id 上的线程相关的所有帖子。

我将尝试使用 M2M 部分,因为我至少有一个工作示例。

【问题讨论】:

    标签: django orm left-join


    【解决方案1】:

    为什么不直接使用M2M 关系,如果需要,您可以使用through

    然后你可以通过 slug 获得一个线程

    thread = Threads.objects.get(slug=slug_name)
    

    然后您可以通过

    访问与线程相关的帖子
    thread.posts_set.all()
    

    【讨论】:

    • 好的。尝试过这种方式,它也可以工作,而不是 thread.posts_set.all() 我使用 thread.posts.all()。感谢您的帮助。
    猜你喜欢
    • 2019-03-28
    • 2018-10-10
    • 2022-01-05
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 2016-09-05
    相关资源
    最近更新 更多