允许同一模型有无限数量的外键的最佳方法是什么?
我现在正在用 django 创建一个论坛,我希望任何人都可以对其他人的评论发表评论。现在,我的“评论”模型中有一个外键,它指向自身,这样我就可以从任何评论中轻松获取父评论。
在我的理论中,这非常有效,因为从任何评论中我都可以得到它的所有子评论,然后从那里继续向下分支以获得每一个子评论。然而,当涉及到从视图到模板获取数据时,我在实际实现这一点时遇到了困难。
我希望可以有无限数量的儿童评论,因为谁知道讨论会持续多久,我不想武断地限制它。我遇到的问题是,您能否将所有这些评论从视图传递到模板,而不会失去它们与其父评论的关系?
目前,这就是我的代码的伪代码:
#the view
def comment_page(request, forum, comment_id):
#this is the main comment that all others will stem from
main_comment = Comment.objects.get(id=comment_id)
children_comments = main_comment.comment_set.all()
#the template
{% for comment in children_comments %}
<p class='comment'>{{comment}}</p>
{% endfor %}
显然,我什至没有尝试在此处获取所有子评论,它只是获取第一篇文章的子评论。我不明白的是,我如何才能浏览这些儿童评论中的每一个,然后获取他们的所有评论,并对每个新评论继续这样做?
在视图中执行此操作最有意义,因为我可以在其中使用 Django 的 QuerySet API,但我不知道如何将所有注释传递到模板而不丢失它们与其父级的关系。我能想到的唯一想法是遍历视图中的所有注释并构建一个我刚刚传递的 html 字符串并简单地显示在模板中,但这似乎是一个可怕的想法,因为它要处理视图中与模板相关的内容。
I'm making a forum with django right now, and I want it so that anyone can comment on anyone else's comment. Right now I have a foreign key in my 'Comment' model that points back to itself so I can get the parent comment easily from any comment.
In my theory this worked great, because from any comment I could get all of its child comments, and then just keep branching down from there to get every single child comment. However I'm having trouble actually implementing this when it comes to getting the data from the view to the template.
I want it to be possible to have an infinite number of child comments, because who knows how long a discussion will last and I don't want to arbitrarily limit it. The problem I'm having is would you get all of those comments from the view to the template without losing their relationship to their parent comment?
Currently this is what the psuedocode for my code looks like:
#the view
def comment_page(request, forum, comment_id):
#this is the main comment that all others will stem from
main_comment = Comment.objects.get(id=comment_id)
children_comments = main_comment.comment_set.all()
#the template
{% for comment in children_comments %}
<p class='comment'>{{comment}}</p>
{% endfor %}
Obviously I'm not even trying to get all the child comments here, it just gets child comments of the very first post. What I don't understand is how can I then go through each of these child comments and then get all of theirs, and keep doing that for each new comment?
It makes the most sense to do it in the view since I am able to use Django's QuerySet API in there, but I don't see how I would be able to pass all of the comments to the template without losing their relationship to their parent. The only idea I can think of is to go through all of the comments in the view and build up a string of html that I just pass and simply display in the template, but that seems like a horrible idea because it'd be dealing with template related stuff in the view.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能想考虑使用 MPTT,例如
django-mptt< /code>
这个可以通过带有
inclusion_tag
包含自身但会对您的数据库产生大量查询:这较旧的问题可能很有趣:
如何我可以使用 django 模板渲染树结构(递归)吗?
You might want to look into using a MPTT such as
django-mptt
this can be implemented by a custom filter with an
inclusion_tag
that includes itself but causes a lots of queries to your db:This older question is probably of interest:
How can I render a tree structure (recursive) using a django template?
编辑:未来的读者,不要这样做,因为内部
for
循环的comment
变量不会替换外部comment 在循环执行过程中变量,导致无限递归。 /Edit
如果您的 HTML 页面需要递归树结构(即一堆嵌套的
标记),您可以编写一个递归“注释”模板。
示例:(未经测试)
for 循环将
comment
模板变量绑定到每个子级,然后再包含其自身。性能说明:除非您的评论集通常很短,否则这可能会非常慢。我建议您将评论设置为不可编辑并缓存结果!
替代解决方案:如果您不需要递归 HTML
标记,您可以编写一个生成器来执行结构的前序遍历并生成 <代码>(深度,评论)对。这在渲染速度方面可能会远远更加高效。
Edit: to future readers, don't do this as the inner
for
loop'scomment
variable does not substitute the outercomment
variable during the loop execution, leading to infinite recursion. /EditIf you need a recursive tree structure in your HTML page (i.e. a bunch of nested
<div>
tags), you can write a recursive "comment" template.Sample: (untested)
The for loop binds the
comment
template variable to each child before including itself.Performance note: Unless your comment sets are often short, this will probably be very slow. I recommend that you make your comments non-editable and cache the result!
Alternate solution: If you don't need the recursive HTML
<div>
tags, you can write a generator that performs a pre-order traversal of the structure and yields(depth, comment)
pairs. This would likely be far more efficient in rendering speed.