看一下 django-reversion
,它为Django模型提供版本控制。可以很容易地添加到现有项目中。
它不使用“当前”指针方法。相反,每次保存对象时将其序列化,并将其存储在单独的Version
模型中,通用外键指向此对象。(默认情况下,关系字段被序列化为主键。)此外,它允许以灵活的方式将Version
分组到Revision
中。
因此,您可以像这样做:
- 当用户上传CSV文件时,只需像往常一样保存更改,但是在执行导入操作的函数上添加
@revision.create_on_success
装饰器,以便该函数对记录所做的任何更改都将存储在单个修订版下。
- 当用户点击“撤消”时,只需还原最新的修订版即可。
以下是如何实现的:
@revision.create_on_success
def import_csv(request, csv):
def undo_last_csv_import(request):
revision = Revision.objects.filter(user=request.user)\
.order_by('-date_created')[0]
revision.revert(delete=True)
它依赖于这样一个事实,即仅在用户导入CSV时创建修订版本。这意味着,如果您计划对其他数据进行版本控制,那么您将需要实现某种标志,以便您可以获取受最新导入影响的记录。然后您可以通过此标志获取记录,获取其最新保存版本,并还原该版本所属的整个修订版本。像这样:
def undo_last_csv_import(request):
some_record = Record.objects.by_user(request.user).from_the_last_import()[0]
latest_saved_version_of_some_record = Version.objects.get_for_date(
some_record,
datetime.now(),
)
latest_saved_version_of_some_record.revision.revert()
这并不是一个完美的解决方案,使用这个应用程序肯定有更好的方法。我推荐查看代码以更好地了解 django-reversion
的工作方式-非常好文档化,找不到没有文档字符串的函数。 ^_^d
(文档也不错,但对我来说有点误导,例如他们编写了Version.objects.get_for_date(your_model, date)
,其中your_model实际上是一个模型实例。)
更新:django-reversion正在积极维护,因此不要太依赖以上代码,最好查看他们的wiki了解如何在django的管理界面外管理版本和修订。例如,版本注释已经支持,这可能会简化一些事情。