tin*_*ino 5 django django-models django-queryset
我有一个非常标准的基本社交应用程序-状态更新(即帖子),每个帖子有多个评论。
给定以下简化的模型,是否有可能使用Django的ORM,高效地检索所有帖子以及与每个帖子相关的最新两个评论,而无需执行N + 1查询?(也就是说,无需执行单独的查询即可获取页面上每个帖子的最新评论。)
class Post(models.Model):
title = models.CharField(max_length=255)
text = models.TextField()
class Comment(models.Model):
text = models.TextField()
post = models.ForeignKey(Post, related_name='comments')
class Meta:
ordering = ['-pk']
Run Code Online (Sandbox Code Playgroud)
Post.objects.prefetch_related('comments').all() 提取所有帖子和评论,但我只想在每个帖子中检索有限数量的评论。
更新:
我了解,如果可以使用Django的ORM完全完成此操作,则可能必须使用的某些版本来完成prefetch_related。只要我避免每页进行N + 1个查询,完全可以进行多个查询。
在Django中处理此问题的典型/推荐方式是什么?
更新2:
使用Django ORM进行简单查询似乎没有直接,简单的方法来有效地完成此操作。以下答案提供了许多有用的解决方案/方法/解决方法,包括:
我不知道哪个标记为正确的,因为我还没有机会尝试所有这些方法-但是我将赏金授予Hynekcer,因为他提出了许多选择。
更新3:
我最终使用了@ user1583799的解决方案。
prefetch_related('comments')将获取帖子的所有评论。
我遇到了同样的问题,数据库是Postgresql。我找到了一个方法:
添加额外的字段related_replies。注意 FieldType 为ArrayField,django1.8dev 支持。我将代码复制到我的项目中(django的版本是1.7),只需更改2行,它就可以工作。(或使用djorm-pg-array)
class Post(models.Model):
related_replies = ArrayField(models.IntegerField(), size=10, null=True)
并使用两个查询:
posts = model.Post.object.filter()
related_replies_id = chain(*[p.related_replies for p in posts])
related_replies = models.Comment.objects.filter(
id__in=related_replies_id).select_related('created_by')[::1] # cache queryset
for p in posts:
p.get_related_replies = [r for r in related_replies if r.post_id == p.id]
Run Code Online (Sandbox Code Playgroud)
当有新评论出现时,更新related_replies。
| 归档时间: |
|
| 查看次数: |
852 次 |
| 最近记录: |