问题描述
我有 2 个模型:发布和评论。像这样:
class Post(models.Model):
content = models.TextField()
class Comment(models.Model)
content = models.TextField()
owner = models.ForeignKey(User,null=False,on_delete=models.CASCADE)
post_parent = models.ForeignKey(
Post,on_delete=models.CASCADE,db_column='post_parent',related_name='comments',)
comment_ref = models.ForeignKey(
'self',null=True,related_name='children_comment'
)
假设评论可以有 1 个级别的子评论。使用帖子的 ID,我想获得 5 条最新评论(不是子评论),每条评论都预取了 3 条最新的子评论。 搜索后我目前的实现是:
sub_comments = Comment.objects.filter(
comment_ref=OuterRef('pk'),post_parent=post_id
).order_by('-timestamp').values_list('id',flat=True)[:3]
queryset = Comment.objects.filter(
comment_ref=None,post_parent=post_id
).select_related('owner').prefetch_related(
Prefetch('children_comment',queryset=Comment.objects.filter(
id__in=Subquery(sub_comments)
),to_attr="cmt"))
那行不通。它不限制预取子评论的数量。请帮帮我 :D
解决方法
您将需要 Comment
表中的日期字段,以便您可以显示最新评论和子评论。
我将在这里介绍另一种模型,以便为我个人查询和编写测试更容易。 模型.py
class Post(models.Model):
content = models.TextField()
class Comment(models.Model)
content = models.TextField()
owner = models.ForeignKey(User,null=False,on_delete=models.CASCADE)
post_parent = models.ForeignKey(
Post,on_delete=models.CASCADE,db_column='post_parent',related_name='comments',)
date_posted = models.DateTimeField()
class ChildComment(models.Model):
parent_comment = models.ForeignKey(
Comment,null=True,related_name="child_comments"
)
视图.py
post = Post.objects.get(id=<some_id>)
comments = Comment.objects.filter(
post_parent_id=post.id
).prefetch_related(
'child_comments'
).order_by(
'-date_posted'
)[:5]
recent_comments = {}
for comment in comments:
recent_comments[comment] = [
comment.child_comments.all().order_by(
'-parent_comment__date_posted'
)[:3]
]
将 recent_comments
传递给模板 context
,然后在模板文件中使用它,例如:
{% for recent_comment,child_comments in recent_comments.items %}
{{ recent_comment.content }}
{% for child_comment in child_comments %}
{{ child_comment.content }}
{% endfor %}
{% endfor %}
,
您需要一个 DateTimeField
来获取 order_by
中的最新评论和子评论,但此查询应该可以工作。如果您要返回数千条评论,这可能不太理想,但一次只有 5 条,这会很快。
comments = Comment.objects.filter(
post_parent_id=post.id
)[:5]
root_comment_ids = [comment.id for comment in comments]
child_comments = Comment.objects.filter(
comment_ref_id__in=root_comment_ids
)[:3]