Django中修订控制模型的良好方法?

2 投票
3 回答
1455 浏览
提问于 2025-04-16 14:24

这是我尝试的结果:

例子 #1

class RevisionControlledValue(models.Model):

    created = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(User)

    value = models.TextField()

    class Meta:
        ordering = ('-created', )

class DjangoPony(models.Model):

    names = models.ManyToManyField(RevisionControlledValue, \
                related_name="fromname_djangopony_set")
    colors = models.ManyToManyField(RevisionControlledValue, \
                 related_name="fromcolor_djangopony_set")

    @property
    def name(self):
        return self.names.latest('created')

例子 #2

class RevisionControlledValue(models.Model):

    created = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(User)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    value = models.TextField()

    class Meta:
        ordering = ('-created', )

class DjangoPony(models.Model):

    @property
    def name(self):
        return self.revisioncontrolledvalue.latest('created')

这两个方法我觉得都有点不太靠谱,特别是内容类型的那个,我本以为应该是个更好的选择。

  • 关于内容类型的那个,模型里并不知道不同类型的修订控制字段,如果我想要不同类型的字段该怎么办呢?

  • 第一个例子中的多对多关系其实并不符合逻辑,因为它实际上是一个一对多的关系。


有什么建议或想法吗? :)

3 个回答

1

@Jason

你不需要创建新的模型……根据Reversion的文档:

保存部分字段
如果你只想保存某些字段到一个版本中,可以在注册方法中指定一个字段参数。

reversion.register(YourModel, fields=["pk", "foo", "bar"])

Reversion经过了很好的测试,它的底层接口几乎可以满足我所有的需求。

2

有一个应用可以做到这一点,叫做 django-reversion。如果你只想对某一个字段进行版本控制,可以把这个字段单独放到一个表里,并建立一个一对一的关系。

1

我觉得你在标题里忘了加个词字段。=) 我想我会用一种方法来保持原来的模型不变。可以从下面这个开始:

class DjangoPony(models.Model):
    name = models.TextField()
    color = models.TextField()

class RevisionControlledValue(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(User)
    value = models.TextField()
    field = models.CharField(max_length=20)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

这个假设你只会用它来处理文本字段。为了让它看起来更漂亮,你可以创建一个新的字段,比如叫ReversionTextField,它在模型保存的时候会自动创建一个版本对象。

撰写回答