Django:使用 Django ORM 实现 JOIN?
Posted
技术标签:
【中文标题】Django:使用 Django ORM 实现 JOIN?【英文标题】:Django: implementing JOIN using Django ORM? 【发布时间】:2011-05-06 17:44:01 【问题描述】:我有一个用 Django 构建的问答类型的网站,具有以下模型:
class Question(models.Model):
title = models.CharField(max_length=70)
details = models.TextField()
class Answer(models.Model):
question_id = IntegerField()
details = models.TextField()
我需要显示一个特定问题及其答案。通常我需要 2 个查询来做到这一点:
Question.objects.get(id=1)
Answer.objects.get(question_id=1)[:10]
我希望使用一个查询来检索所有内容。在 mysql 中是:
SELECT *
FROM Question JOIN Answer ON Question.id=Answer.question_id
WHERE Question.id=1
LIMIT 10
无论如何我可以通过 Django 的 ORM 做到这一点吗?
extra()
在这种情况下会有帮助吗?
【问题讨论】:
【参考方案1】:#考虑书籍和出版商之间的外键关系
class Publisher(models.Model):
name = models.CharField(max_length=100)
eclass Book(models.Model):
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
#获取图书的出版商名称
book = Book.objects.select_related('publisher').get(id=1)
book.publisher.name
#获取具有特定出版商的书籍
publisher = Publisher.objects.prefetch_related('book_set').get(id=1)
books = publisher.book_set.all()
更多 https://kwikl3arn.com/django/JOINS
【讨论】:
【参考方案2】:考虑使用models.ForeignKey(Question)
而不是question_id = IntegerField()
。
这是表达您试图描绘的问题和答案之间关系的最佳(更具关联性)方式。
通过这种方式,您只需拨打Answers.objects.filter(question_id=<id>)
即可获得所需的内容。
【讨论】:
使用ForeignKey
确实是正确的方法,但此答案中提供的查询调用仅返回Answer
对象,而问题是如何获取Question
和@987654327 @ 一个查询中的对象。【参考方案3】:
这正是select_related() 所做的。唯一的问题是 你必须从答案模型开始,而不是从问题开始,但是 结果是一样的:
answers = Answer.objects.filter(question_id=1).select_related()
现在每个答案对象都有一个预取的“问题”属性,并且 访问它不会再次访问数据库。
【讨论】:
谢谢,如果我们需要相关表的外键名称,假设表A与B相关,B与C相关。(所有表只有“name”和“id”)。我们希望通过相关的 C 表对象连接 A 的每个条目。 如果question_id
只是一个整数,而Answer
没有为Question
提供models.ForeignKey
字段,这将如何工作?【参考方案4】:
class Question(models.Model):
title = models.CharField(max_length=70)
details = models.TextField()
class Answer(models.Model):
question = models.ForeignKey('Question')
details = models.TextField()
id = <whatever_id>
answers = Question.objects.get(id=id).answer_set.all()
【讨论】:
以上是关于Django:使用 Django ORM 实现 JOIN?的主要内容,如果未能解决你的问题,请参考以下文章