我在主题详情视图中显示评论。恰好发生了两个查询
在这个视图中:一个获取主题,一个获取评论列表。一世
了解自select_related
技术无法在此使用
在视图中创建了两个不同的查询集。有没有
将查询数量减少到一个的方法?
申请代码如下。
class Topic(models.Model):
headline = models.CharField(max_length=400)
description = models.TextField()
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, related_name='topics')
class Comment(models.Model):
headline = models.CharField(blank=True, max_length=400)
description = models.TextField()
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, related_name='comments')
topic = models.ForeignKey(Topic, related_name='comments')
class TopicDetail(DetailView):
queryset = Topic.objects.select_related('author').all()
context_object_name = 'topic'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
topic = self.object
context['comments'] = topic.comments.select_related('author').all()
return context
{{ topic.headline }}
{{ topic.description }}
{{ topic.created }}
{{ topic.modified }}
{{ topic.author }}
{% for comment in comments %}
{{ comment.headline }}
{{ comment.description }}
{{ comment.author }}
{% endfor %}
答案 0 :(得分:4)
查看反向foreignKey查找的 prefetch_related 方法。这实际上不会减少SQL查询的数量,但是django将合并python相关的注释和主题。
在文档中:https://docs.djangoproject.com/en/1.8/ref/models/querysets/#prefetch-related
此外,您应该确保为您的字段提供不同的相关名称,否则您将遇到调用它们的问题:
author = models.ForeignKey(User, related_name='user_comments')
topic = models.ForeignKey(Topic, related_name='topic_comments')
这样你就可以编写单行查询(但是2次SQL命中):
topics = Topic.objects.prefetch_related('topic_comments').select_related('author').all()
然后例如:
{% for topic in topics %}
{% for comment in topic.topic_comments.all %}
{{ ... }}
{% endfor %}
{% endfor %}
答案 1 :(得分:1)
即使在纯SQL这样的"单一"查询会很难。
基本上您需要在每条评论中重复所有主题数据!就像在这个伪代码中一样:
Select comment.*, topic.*
From comments
Right Join topic
这是大量的数据处理/传输开销。整个操作应该花费更多的时间,资源然后分开查询。
如果您真的需要它,那么只需在评论主题模型中编写自定义函数,使用纯SQL。