【问题标题】:Making a copy of an object's initial state before saving在保存之前复制对象的初始状态
【发布时间】:2016-11-04 08:57:47
【问题描述】:

对于我的 Django 应用程序,我希望保留所有对象的完整编辑历史记录。作为其中的一部分,我重写了模型的 save() 方法,其中一部分如下所示:

# Replicate the current version (from the db) with all attributes unchanged
new_ver = self.__class__.objects.get(pk=self.pk).save(force_insert=True)


# Update the current version in the database with the new attributes
super(CodexBaseClass, self).save(*args, force_update=True, **kwargs)

传递给 save() 方法的“self”是表单生成的对象的新版本。这段代码试图做的是

(1) 复制当前出现在数据库中的对象(即:复制表单修改之前的数据),然后强制插入此数据,以便将其复制为新行

(2) 使用通过表单提交的对象的新版本更新现有行。

问题出在这两行代码的第一行 - 它生成了一个 DoesNotExist 异常。该对象确实存在,因此我目前认为问题在于它尝试读取的数据库行当前已锁定。

所以我的问题是:有没有一种方法可以修改/替换第一行,以便我拥有 initial 数据的副本,就像在表单修改之前一样?

谢谢。

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    如果要插入具有相同属性的新对象,只需更改对象的主键,并保存即可。

    new_ver = self.__class__.objects.get(pk=self.pk)
    new_ver.pk = None
    new_ver.save()
    

    使用 None 作为主键会自动生成它。如果您查看django documentation,您可以获得更多信息。

    如果您需要,您也可以复制您的对象,注意成本可能很昂贵:

    from copy import deepcopy
    
    ver = self.__class__.objects.get(pk=self.pk)
    new_ver = deepcopy(ver)
    new_ver.pk = None
    new_ver.save()
    # Do what you need with ver object
    

    【讨论】:

    • 我已经尝试过了。它给出了同样的例外。 self.__class__.objects.get(pk=self.pk) 似乎是问题所在。 self.pk 引用的对象是 UpdateView 正在编辑的对象,所以我现在似乎无法从数据库中读取该特定对象......至少不能使用这种方法。
    • 你试过我的答案了吗?
    【解决方案2】:

    你应该看看django-reversion

    django-reversion 是 Django Web 框架的扩展,它 为模型实例提供版本控制。

    文档link

    特点

    • 回滚到模型实例历史中的任何时间点。
    • 恢复已删除的模型实例。
    • 简单的管理集成。

    【讨论】:

      猜你喜欢
      • 2010-12-27
      • 2021-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 2017-08-14
      • 1970-01-01
      • 2016-11-06
      相关资源
      最近更新 更多