3

ユーザーが誤って複数のオブジェクトを変更する可能性がある場合に備えて、django-reversionを使用してdjangoプロジェクトに「undo」機能を実装しようとしています。オブジェクトを1つずつ元に戻す必要があるため、管理パネルの使用は機能しません。

私の問題は、複数のオブジェクトに関するデータを保持するリビジョンを作成できないことです。
やっても

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

その場合、この変更をグループ化するリビジョンにアクセスできません。「1つのオブジェクト1つのrevision.models.Version」の方法で分割されます。

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

私も試してみました

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

ただし、削除された1つのResオブジェクトに対して1つのバージョンのみが返されます。何かが足りないようです。

4

2 に答える 2

9

tl;dr-リビジョンは「元に戻す」ものではありません。それはあなたが復元するものです。したがって、元に戻すとは、元にしたいものの前に発生した最新のリビジョンを見つけて、revert()を呼び出して復元する場合です。

django-reversionのデータモデルは、リビジョンとバージョンに基づいています。リビジョンは1つ以上のバージョンで構成され、バージョンは1つの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()

この時点で、最後のリビジョンに戻すことで、2番目の編集を「元に戻す」ことができます。

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

次のように削除して復元することもできます。

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

したがって、単一のモデル、または一緒に保存されたモデルのグループの以前の状態に戻すことができます。しかし、「今やったことを元に戻す」と言う方法はありません。代わりに、「この時点のようになる」ように復帰を指示する必要があります。

あなたの場合、一括削除を元に戻したい場合は、次のように行うことができます。

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

ただし、この場合、SomeModelの他のリビジョンがいつでも作成される可能性があるため、非常に愚かな競合状態になります。

于 2013-03-23T14:35:02.943 に答える
1

私はついにそれを手に入れました。

問題1:複数のオブジェクトに関連する変更を1つのリビジョンに保存する

解決策:TransactionMiddlewareをMIDDLEWARE_CLASSESに追加します

問題2:機能を元に戻す/変更を元に戻す

まあ、これは紛らわしいです。オブジェクトを以前の既知の状態に復元できる変更を元に戻すことはできません。また、オブジェクトでreversion.create_revision()を使用すると、ビューを変更すると、オブジェクトを変更した後、そのオブジェクトに関するデータが保存されます。複数のオブジェクトを変更するビューがある場合は、実際に変更を加える前にリビジョンを作成する必要があります。

これは管理パネルにも表示されます。オブジェクトを変更すると、新しいログエントリが表示されます。ただし、最新バージョンを選択できない場合よりもその変更を元に戻したい場合(オブジェクトの現在の状態と同じです)、代わりにのバージョンを選択する必要があります。

于 2013-03-25T17:32:03.783 に答える