Python Django中的模型历史
在Django中,如何处理与Post对象关联的图像的并发更改? 这是一个以前被问过的问题,但不完全涵盖相同的问题。我已经通读了这些(、、和),但问题略有不同 我有一个博客文章模型(速度的伪代码),它包含标题、摘要和正文以及相关的图片Python Django中的模型历史,python,django,django-models,version,revision-history,Python,Django,Django Models,Version,Revision History,在Django中,如何处理与Post对象关联的图像的并发更改? 这是一个以前被问过的问题,但不完全涵盖相同的问题。我已经通读了这些(、、和),但问题略有不同 我有一个博客文章模型(速度的伪代码),它包含标题、摘要和正文以及相关的图片 class Post(models.Model): title = CharField abstract = TextField body = TextField class Image(models.Model): post =
class Post(models.Model):
title = CharField
abstract = TextField
body = TextField
class Image(models.Model):
post = ForeignKey(Post)
imagefile = ImageField
现在,我想添加的是存储此Post
模型更改的历史记录的功能。我想到了两种可能性:
可能性1
class PostHistory(models.Model):
post = ForeignKey(Post)
title_delta = TextField
abstract_delta = TextField
body_delta = TextField
但是,这有一个问题,即它存储的增量没有变化(例如,标题
没有变化,并且正文
字段只有一个增量。也就是说,当多个字段发生变化时,它适合“1个修订==1个完整修订”
可能性2
class PostRevision(models.Model):
post = ForeignKey(Post)
field = CharField #Field name
delta = TextField
通过两种不同的方法,这成功地为我提供了该字段的差异历史记录,我将使用它生成(性能略高于内置)。我现在遇到的两个问题与主对象的生成有关(即链中的顶部修订)
所提出的问题是:如何处理与Post对象关联的图像的并发更改?这些更改将通过
Post
模型的正文
字段中的引用进行更改(这是一个标记格式的文本字段,然后在表单的POST
上进行编辑,以添加图像字段的URL引用)。处理此问题的最佳方法是在修订版和Post
对象上使用M2M字段,允许图像始终与PostRevision
对象一起存储?我认为您应该坚持选项1。
一个想法是建立一个自动修订系统。
下面是我将如何做和介意一些语法错误,我键入了我的脑袋
class A(models.Model):
field1 = ...
field2 = ...
def save():
if bla_bla_updated:
A_revisions.objects.create(
field1=self.fields1, field2=self.fields2,
a=self)
super(A, self).save()
class A_revision(models.Model):
field1 = ...
field2 = ...
a = models.ForeignKey(A)
revision = models.IntegerField()
def save():
self.revision = (A_revision.objects.get(a=self.a)
.order_by('id').revision) + 1
super(A_revision, self).save()
我同意@rickard zachrisson的观点,你应该坚持方法1。不过我会做一些细微的改变(顺便说一句伪代码): 您的最新版本将始终在
Post
中,并且您的更改历史记录在pk
中的顺序在PostHistory
中,这很容易区分更改。我会复制数据,因为存储成本很低,而存储增量是一个pita。如果您进行了多次编辑或希望将当前版本与原始版本进行比较Delta基本上是无用的。AbstractPost中的任何模型更改都会反映在Post
和PostHistory
中
图像
已设置为Post键,因此内容保持整洁。您可以选择清理帖子中的图像。保存()函数,但我可能会选择一个post_保存信号,以保持代码更干净。我读得不好或理解错误,但您是否希望保存每个字段修订版或对象作为一个整体?嗯,这是进退两难的一部分,我是否每次都保存整个对象的差异(可能性1)(对于许多字段而言,这基本上是“零更改”,或者为更改的单个字段保存差异(可能性2)?如果一个版本的标题与另一个版本的标题相同,那是不是很糟糕?不,这是一个完全可以接受的情况。假设我选择可能性1,那么这就清除了匹配增量、字段和对象的问题,并保持其原子性-一个版本就是一个版本。后续问题(绑定图像字段),我可能会用图像和修订对象之间的M2Ms来解决这个问题,这听起来合理吗?有一个应用程序可以做到这一点:感谢上面提到的——关于复制数据而不是差异,当文本可能有几千字长,并且一些更改可能小到更改一个完整的sto时,您还会这么说吗p到逗号?我不会预先优化,直到您有更多的数据或存储空间是一个问题(也许压缩数据然后)。这取决于您将版本与另一个版本进行比较的频率。如果您的差异跟踪从一个版本到下一个版本的变化,那么您就有相当多的数据需要读取/处理,只是为了比较两个版本。如果您只存储原始版本的差异,那么随着差异的增大,您会损失更多的存储空间。这是一种折衷方法。super(Post,self).save()
将不会返回Post
实例。
class AbstractPost(models.Model):
title = CharField
abstract = TextField
body = TextField
class Meta:
abstract = True
class Post(AbstractPost):
def save(self):
post = super(Post, self).save()
PostHistory.objects.create(
post=post,
title=post.title,
abstract=post.abstract,
body=post.body,
)
class PostHistory(AbstractPost):
post = ForeignKey(Post)
class Meta:
ordering = ['-pk']
class Image(models.Model):
post = ForeignKey(Post)
imagefile = ImageField