简体   繁体   English

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

[英]django-reversion undo feature - recovering multiple objects

I'm trying to implement 'undo' feature in django project with django-reversion in a case when user can accidentally modify multiple objects. 我正在尝试使用django-reversion在django项目中实现“撤消”功能,以防用户意外修改多个对象。 Using admin panel won't work as one has to revert objects one-by-one. 使用管理面板将无法正常工作,因为必须逐个还原对象。

My problem is that I am unable to create revision that holds data about more than one object. 我的问题是我无法创建包含多个对象数据的修订版。
Even when I do 即使我这样做

with reversion.create_revision():
    Res.object.all().delete()

then I cannot access revision that groups this change. 然后我无法访问将此更改分组的修订版。 It's splitted in a "one object one revision.models.Version" manner. 它分为“one object one revision.models.Version”方式。

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

I've tried also through 我也试过了

reversion.models.Revision.objects.all().order_by('-date_created')[0].version_set.all()

but it also returned only one Version for one deleted Res object. 但它也只为一个已删除的Res对象返回了一个版本。 Seems like I'm missing something. 好像我错过了什么。

tl;dr - A revision isn't something you 'undo'. tl; dr - 修订不是你'撤消'的东西。 It's something you restore. 这是你恢复的东西。 Thus, undoing is a case of finding the most recent revision that occurred before the thing you want to undo, and restore it by calling revert(). 因此,撤消是查找要撤消的事物之前发生的最新修订的情况,并通过调用revert()来恢复它。

The data model for django-reversion is based around Revisions and Versions. django-reversion的数据模型基于修订版和版本。 A Revision consists of one or more Versions, and a Version represents the serialized state of one Django model. Revision包含一个或多个Versions,Version表示一个Django模型的序列化状态。

django-reversion allows you to roll back to the state of any previous Version or Revision. django-reversion允许您回滚到任何先前版本或修订版的状态。 This is similar to, but not identical to an undo functionality. 这与撤消功能类似但不完全相同。

Consider the following workflow: 请考虑以下工作流程:

# 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()

At this point, you can 'undo' the second edit by reverting to the last revision. 此时,您可以通过还原到上一个修订来“撤消”第二个编辑。

# 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()

You can also delete and recover like so: 你也可以这样删除和恢复:

# 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()

So you can revert to a previous state of a single model, or a group of models saved together. 因此,您可以恢复到单个模型的先前状态,或者保存在一起的一组模型。 However, there is no way to say 'undo what I just did'. 但是,没有办法说'撤消我刚刚做的'。 Instead, you have to tell reversion 'become like you were at this time'. 相反,你必须告诉reversion'变得像你现在这样'。

In your case, if you wanted to undo a bulk delete, you could do it like this: 在您的情况下,如果您想要撤消批量删除,您可以这样做:

# 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()

In this case, however, you'll get a very silly race condition, since other revisions for SomeModel could be created at any time. 但是,在这种情况下,您将获得非常愚蠢的竞争条件,因为可以随时创建SomeModel的其他修订版。

I finally got it. 我终于明白了。

Issue 1: Store changes related to multiple objects in a single Revision 问题1:在单个版本中存储与多个对象相关的更改

Solution: add TransactionMiddleware to MIDDLEWARE_CLASSES 解决方案:将TransactionMiddleware添加到MIDDLEWARE_CLASSES

Issue 2: Undo feature / reverting changes 问题2:撤消功能/还原更改

Well, this is confusing. 嗯,这很令人困惑。 You cannot REVERT CHANGES you can RESTORE OBJECT to previously known state. 您无法撤消更改,您可以将对象恢复到以前已知的状态。 And using reversion.create_revision() in your object-altering views stores data about that object after changing it . 改变之后使用reversion.create_revision()在你改变对象的视图存储数据有关该对象。 If you have view that modify multiple object then you have to create revision before making actual changes. 如果您有修改多个对象的视图,则必须在进行实际更改之前创建修订。

This is also visible in admin panel. 这在管理面板中也可见。 If you change your object than a new log entry will appear. 如果更改对象,则会显示新的日志条目。 But if you want to revert that change than you cannot select newest version -- it is identical with the current state of the object -- instead you have to choose the previous one. 但是如果你想要恢复这个变化而不是你不能选择最新的版本 - 它与对象的当前状态相同 - 而是你必须选择一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM