递归地将pymysql注释objects转换为树
Converting pymysql Comment objects to tree recursively
我正在尝试创建一个评论系统作为业余爱好项目的一部分,但我不知道如何在从数据库中获取评论后对评论 object 进行递归排序。我正在使用具有以下数据模型的关系数据库:
class Comment(Base):
__tablename__ = 'comments'
id = Column(Integer, primary_key=True)
comment = Column(String(), nullable=False)
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
post_id = Column(Integer, ForeignKey('posts.id'), nullable=False)
parent_id = Column(Integer, ForeignKey('comments.id'), nullable=False)
从数据库中获取数据后,我需要在树中对这些 object 进行排序。例如,示例输入可以是:
comments = [
<models.Comment object at 0x104d80358>,
<models.Comment object at 0x104d803c8>,
<models.Comment object at 0x104d80470>,
<models.Comment object at 0x104d80518>,
<models.Comment object at 0x104d805c0>,
<models.Comment object at 0x104d80668>
]
预期结果可能是:
comment_dict = {1: {'comment':<Comment.object>, 'children':[]},
{2: {'comment':<Comment.object>, 'children':[<Comment.object>, ...]},
{3: {'comment':<Comment.object>, 'children':[]},
{4: {'comment':<Comment.object>, 'children':[<Comment.object>, ...]} ...
任何评论 object 都可以有无限数量的 children。几乎就像 reddit 和其他类似社交媒体网站上使用的评论系统。
对于渲染,我使用的是 flask 和 Jinja,并且可能会做一些我在文档中找到的类似的事情:
<ul class="sitemap">
{%- for item in sitemap recursive %}
<li><a href="{{ item.href|e }}">{{ item.title }}</a>
{%- if item.children -%}
<ul class="submenu">{{ loop(item.children) }}</ul>
{%- endif %}</li>
{%- endfor %}
我不知道在执行此操作之前如何对数据进行排序。
非常简单的方法是这样的:
def comments_to_dict(comments):
result = {}
for comment in comments:
result[comment.id] = {
'comment': comment,
'children': []
}
for comment in comments:
result[comment.parent_id]['children'].append(comment)
return result
所以首先用 children
填充根元素为空,然后在第二遍中填充子元素。这可以通过只对 comments
:
进行一次传递来进一步改进
def comments_to_dict(comments):
result = {}
for comment in comments:
if comment.id in result:
result[comment.id]['comment'] = comment
else:
result[comment.id] = {
'comment': comment,
'children': []
}
if comment.parent_id in result:
result[comment.parent_id]['children'].append(comment)
else:
result[comment.parent_id] = {
'children': [comment]
}
return result
此处的解决方案符合您向我们展示的预期输出。
如果你想要一棵真正的树,那么试试这个
def comments_to_dict(comments):
index = {}
for comment in comments:
index[comment.id] = {
'comment': comment,
'children': []
}
for obj in index.itervalues():
pid = obj['comment'].parent_id
index[pid]['children'].append(obj)
return index
我正在尝试创建一个评论系统作为业余爱好项目的一部分,但我不知道如何在从数据库中获取评论后对评论 object 进行递归排序。我正在使用具有以下数据模型的关系数据库:
class Comment(Base):
__tablename__ = 'comments'
id = Column(Integer, primary_key=True)
comment = Column(String(), nullable=False)
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
post_id = Column(Integer, ForeignKey('posts.id'), nullable=False)
parent_id = Column(Integer, ForeignKey('comments.id'), nullable=False)
从数据库中获取数据后,我需要在树中对这些 object 进行排序。例如,示例输入可以是:
comments = [
<models.Comment object at 0x104d80358>,
<models.Comment object at 0x104d803c8>,
<models.Comment object at 0x104d80470>,
<models.Comment object at 0x104d80518>,
<models.Comment object at 0x104d805c0>,
<models.Comment object at 0x104d80668>
]
预期结果可能是:
comment_dict = {1: {'comment':<Comment.object>, 'children':[]},
{2: {'comment':<Comment.object>, 'children':[<Comment.object>, ...]},
{3: {'comment':<Comment.object>, 'children':[]},
{4: {'comment':<Comment.object>, 'children':[<Comment.object>, ...]} ...
任何评论 object 都可以有无限数量的 children。几乎就像 reddit 和其他类似社交媒体网站上使用的评论系统。 对于渲染,我使用的是 flask 和 Jinja,并且可能会做一些我在文档中找到的类似的事情:
<ul class="sitemap">
{%- for item in sitemap recursive %}
<li><a href="{{ item.href|e }}">{{ item.title }}</a>
{%- if item.children -%}
<ul class="submenu">{{ loop(item.children) }}</ul>
{%- endif %}</li>
{%- endfor %}
我不知道在执行此操作之前如何对数据进行排序。
非常简单的方法是这样的:
def comments_to_dict(comments):
result = {}
for comment in comments:
result[comment.id] = {
'comment': comment,
'children': []
}
for comment in comments:
result[comment.parent_id]['children'].append(comment)
return result
所以首先用 children
填充根元素为空,然后在第二遍中填充子元素。这可以通过只对 comments
:
def comments_to_dict(comments):
result = {}
for comment in comments:
if comment.id in result:
result[comment.id]['comment'] = comment
else:
result[comment.id] = {
'comment': comment,
'children': []
}
if comment.parent_id in result:
result[comment.parent_id]['children'].append(comment)
else:
result[comment.parent_id] = {
'children': [comment]
}
return result
此处的解决方案符合您向我们展示的预期输出。
如果你想要一棵真正的树,那么试试这个
def comments_to_dict(comments):
index = {}
for comment in comments:
index[comment.id] = {
'comment': comment,
'children': []
}
for obj in index.itervalues():
pid = obj['comment'].parent_id
index[pid]['children'].append(obj)
return index