我无法弄清楚如何在Django中最好地实现文档(段落)修订系统。
我想逐段保存文档的修订历史记录。换句话说,会有一个Document
类,其ManyToManyField
到Paragraph
。为了维护段落的顺序,可以创建第三个类ParagraphContainer
。
我的问题是,在Django中实现这一点的好方法是什么,以便在有人在现有段落之间添加新段落时保持段落的顺序?
一种显而易见的方法是在ParagraphContainer
类中使用position属性,但是必须在插入(或删除)段落后的所有段落中更新此字段。链接列表是另一种选择,但我担心检索整个文档可能会非常慢。有什么建议吗?
答案 0 :(得分:2)
编辑通常使用 Piece Table 解决此问题。该表是一个对象列表,指向a)内存中连续的字符跨度,以及b)共享公共属性。表中各部分的顺序用于将文档中的字符地址映射到存储器,反之亦然。通过重新排序片表,您可以有效地重新排序文档而不会移动任何东西。关键点在于,表格本身独立于构成文档内容的对象。
因此,映射段落顺序的一种方法是使用peice表的简化版本。这可以像文档顺序中的para-id列表一样简单。当你需要更改某些内容时,你需要获取列表,取消删除它,让你在列表上编辑,挑选并保存。
该表的另一个优点是它极大地简化了实现撤消。历史文件是对表的编辑的简单列表,撤消/重做是将特定编辑反转或重新应用于表的问题,数据本身不会改变。这应该适用于您想要进行的任何版本控制。
答案 1 :(得分:1)
如果您添加order
属性through
table to your ManyToManyField
,则可以解决此问题:
class Paragraph(models.Model):
text = models.TextField()
class Document(models.Model):
paragraphs = models.ManyToManyField(Paragraph, through='DocumentParagraph')
class DocumentParagraph(models.Model):
paragraph = models.ForeignKey(Paragraph)
document = models.ForeignKey(Document)
order = models.PositiveIntegerField()
对于cource,您必须添加一些自定义方法来更新订单等,因为您可以查看覆盖Paragraph.save
或使用post_save
- 信号,例如!