这是一个严格的学术问题,经过一番混乱-但基本上我想知道如果我从父子关系开始(django模型)如何制作reddit风格的嵌套评论系统
鉴于每个记录的父级以及与该记录相关联的一些数据的知识,如何创建任意深度的树结构,其中树中的每个节点(记录)不仅包含有关其与其他节点的关系的信息记录(由于在树中的位置),但也有与其关联的数据
class Record(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
parent = models.ForeignKey('Record', verbose_name='Hierarchical Parent', on_delete=models.CASCADE, null=True, blank=True)
data = models.TextField()
generation = models.IntegerField()
第一个问题是获取父子关系(尚未担心将数据与父关系相关)。
这个人Django how to make ul li hierachy from a self reference model完成了将类似的数据结构转换为嵌套无序html列表的工作,我也尝试过,效果很好。
但是我想要一个可以使用的数据结构,例如字典之类的东西。
最初,当我开始研究此问题时,我并没有考虑使用Reddit式评论,而是实际上正在将hierarchical db(这很久以前很流行)移到了django中应用程序中,我的Django“记录”表代表了层次关系:
Name | Parent
----------------
Account | None
Loan | Account
Escrow | Loan
Person | Account
AccHx | Account
LoanHx | Loan
我想要类似的东西
{'Account':
{'Loan':
{'LoanHx':{},
'Escrow':{}
},
'Person':{},
'AccHx':{}
}
}
并且能够使用defaultdict集合来做到这一点(很多HN发布了解决方案的灵感,例如How do I build a tree dynamically in Python)
我的解决方案:
def add_element(root, path, data):
if len(path) == 1:
root[path[0]] = data
else:
add_element(root[path[0]], path[1:], data)
import collections
tree = lambda: collections.defaultdict(tree)
root = tree()
# add_element(root, ['toplevel', 'secondlevel', 'thirdlevel'], 1)
# add_element(root, ['toplevel', 'anotherlevel'], 2)
selected_records = Record.objects.all()[0:5]
#I have a generation field
for sr in selected_records:
if sr.generation == 0:
add_element(root, [sr.name], {})#sr.data)
elif sr.generation == 1:
add_element(root, [sr.parent.name, sr.name], {})#sr.data)
elif sr.generation == 2:
add_element(root, [sr.parent.parent.name, sr.parent.name, sr.name], {})#sr.data)
elif sr.generation == 3:
add_element(root, [sr.parent.parent.parent.name,
sr.parent.parent.name, sr.parent.name, sr.name], {})#sr.data)
因此,假设我有sr.data(即,如果我正在构建嵌套评论系统,则为评论内容)作为我的数据参数进入递归add_element(root,path,data)函数,然后在下一个递归中会收到TypeError-'str'不支持数据分配。因此,我将数据参数(新节点)设置为字典,以便可以继续递归。这样就成功创建了多级dict结构,如上所示。
但是如果我想要类似的东西怎么办?
{'Account':
{'fields':['id','name',....],
'children':
{'Loan':
{'fields':['id','name',....],
'children':
{'LoanHx':{'fields':['id','name',....],
'children':{}},
....
我该如何更改add_element递归函数以适应呢?现在我已经把所有内容都写完了,我想我有个主意。