2010-07-29 62 views
4

我试图在Django应用程序中存储文档的各个部分。该模型是这样的:Django:存储分层数据

class Section(models.Model): 
    project = models.ForeignKey(Project) 
    parent_section = models.ForeignKey('Section', blank=True, null=True, related_name='child_set') 
    predecessor_section = models.ForeignKey('Section', blank=True, null=True, related_name='predecessor_set') 
    name = models.CharField(max_length=100) 
    text = models.TextField(blank=True, null=True) 

我创造了一大堆段,将它们链接(parent_section,predecessor_section),并通过调用他们的每一个保存方法将它们存储。但是,在保存后查看表时,即使在保存之前已将对象附加到它们,parent_section_id和predecessor_section_id也未设置。

我认为它是与事实有些parent_section实例没有分配一个ID作为实例已尚未存储,但使用人工交易未能解决的问题做。

上有什么想法?

干杯, 最大

+0

我只是试图存储实际实例之前,家长和前作参考,但它并没有帮助。 – Max 2010-07-29 12:34:41

回答

0

对象在将它们保存在Django ORM中之前,您没有ID。

所以我说你需要保存()的对象,然后在你的父/子段引用它(并重新保存的部分)。

然而,另一种选择存储PREC和下一个作为指针是存储一个sequence_index(由10间隔开以允许插入件进一步重新排序wiothout)本索引和顺序。

+0

另一个示例存储在数据库中的有序数据:http://stackoverflow.com/questions/547022/how-do-i-store-orders#547076 – makapuf 2010-07-29 13:04:33

+0

两次扫描所有的实体和调用save()也应该工作(因为参考文献是最初设定的)。由于某种原因,它不... – Max 2010-07-29 13:22:28

+0

好的。我想我解决了它。你是对的,再次设置关系是必要的。我存储实体一次,并在第二遍,我手动设置关系的ID(section.parent_section_id = section.parent_section.id)。 Django似乎只在关系被分配时自动设置它们。已经连接的关系在save()中被忽略。 – Max 2010-07-29 13:31:12

0

尝试做保存()上所有的对象,然后更新它们之间的关系,然后保存()所有的人再次。

当你指定一个外键,相关的(目标)对象的ID被复制。因为在分配关系(parent_section,predecessor_section)相关的对象没有一个id还的那一刻,你会得到一个时髦的结果:

A = Section(name='A') 
B = Section(name='B') 
B.parent_section = A 
A.save() 
B.save() 
B.parent_section # this will say A 
B.parent_section_id # this will say **None** 

但这应该工作:

A = Section(name='A') 
B = Section(name='B') 
A.save() 
B.save() 
B.parent_section = A 
B.parent_section # this will say A 
B.parent_section_id # this will say A.id 
B.save() # don't forget this one :) 
+0

不太清楚你的意思是“更新他们的关系”。关系在保存实体之前已经设置好了。但是我保存了所有实体两次,这意味着任何在第一次运行中没有保留的关系都会在第二次运行中持续存在。 - 关系没有保存... – Max 2010-07-29 13:10:27

+0

它不会工作。相关对象在将它们分配给关系之前需要有它们的ID。在2个循环中执行:首先创建所有对象,仅使用其内部属性(与其他节对象无关),然后保存()所有对象。然后在另一个循环中分配所有关系(parent_section,predecessor_section),然后再次保存()。 – 2010-07-29 13:32:05

+0

是的,你是对的。看到我的帖子上面。 – Max 2010-07-29 13:53:27