django-reversion undo功能 - 恢复多个对象

Jak*_*zik 3 python django undo django-reversion

我正在尝试使用django-reversion在django项目中实现"撤消"功能,以防用户意外修改多个对象.使用管理面板将无法正常工作,因为必须逐个还原对象.

我的问题是我无法创建包含多个对象数据的修订版.
即使我这样做

with reversion.create_revision():
    Res.object.all().delete()
Run Code Online (Sandbox Code Playgroud)

然后我无法访问将此更改分组的修订版.它分为"one object one revision.models.Version"方式.

In [103]: reversion.models.Version.objects.all()
Out[103]: [<Version: #00001>, <Version: #00002>]
Run Code Online (Sandbox Code Playgroud)

我也试过了

reversion.models.Revision.objects.all().order_by('-date_created')[0].version_set.all()
Run Code Online (Sandbox Code Playgroud)

但它也只为一个已删除的Res对象返回了一个版本.好像我错过了什么.

Dav*_*ave 9

tl; dr - 修订不是你'撤消'的东西.这是你恢复的东西.因此,撤消是查找要撤消的事物之前发生的最新修订的情况,并通过调用revert()来恢复它.

django-reversion的数据模型基于修订版和版本.Revision包含一个或多个Versions,Version表示一个Django模型的序列化状态.

django-reversion允许您回滚到任何先前版本或修订版的状态.这与撤消功能类似但不完全相同.

请考虑以下工作流程:

# Create a Revision containing two Versions.
with reversion.create_revision():
    a = SomeModel.objects.create(name="A version 1")
    b = SomeModel.objects.create(name="B version 1")

# Create a Revision containing to Versions.
with reversion.create_revision():
    a.name = "A version 2"
    a.save()
    b.name = "B version 2"
    b.save()
Run Code Online (Sandbox Code Playgroud)

此时,您可以通过还原到上一个修订来"撤消"第二个编辑.

# Revert just 'a' to version 1. This is the last but one revision.
reversion.get_for_object(a)[1].revert()

# Or, revert 'a' and 'b' to version 1.
reversion.get_for_object(b)[1].revision.revert()
Run Code Online (Sandbox Code Playgroud)

你也可以这样删除和恢复:

# Store the pk of 'a', then delete it.
a_pk = a.pk
a.delete()

# Recover 'a' via it's primary key.
reversion.get_deleted(SomeModel).filter(object_id=a_pk).revert()
Run Code Online (Sandbox Code Playgroud)

因此,您可以恢复到单个模型的先前状态,或一组保存在一起的模型.但是,没有办法说'撤消我刚刚做的'.相反,你必须告诉reversion'变得像你现在这样'.

在您的情况下,如果您想要撤消批量删除,您可以这样做:

# Save a revision containing all SomeModel instances.
with reversion.create_revision():
    for obj in SomeModel.objects.all():
        obj.save()

# Delete them all.
SomeModel.objects.delete()

# Revert back to the previous revision, where nothing was deleted.
Revision.objects.filter(version__content_type=ContentType.objects.get_for_model(SomeModel)).order_by("-date_created")[0].revert()
Run Code Online (Sandbox Code Playgroud)

但是,在这种情况下,您将获得非常愚蠢的竞争条件,因为可以随时创建SomeModel的其他修订版.