File: api.rst

package info (click to toggle)
django-reversion 6.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 888 kB
  • sloc: python: 2,893; makefile: 22; sh: 7; sql: 1
file content (484 lines) | stat: -rw-r--r-- 12,750 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
.. _api:

django-reversion API
====================

Use the django-reversion API to build version-controlled apps. See also :ref:`Views` and :ref:`Middleware`.


Overview
--------

Registering models
^^^^^^^^^^^^^^^^^^

Models must be registered with django-reversion before they can be used with the API.

.. code:: python

    from django.db import models
    import reversion

    @reversion.register()
    class YourModel(models.Model):

        pass

.. Hint::
    If you're using the :ref:`admin`, model registration is automatic. If you’re using django-reversion in a management command, make sure you call ``django.contrib.admin.autodiscover()`` to load the admin modules before using the django-reversion API.

.. include:: /_include/post-register.rst


Creating revisions
^^^^^^^^^^^^^^^^^^

A *revision* represents one or more changes made to your model instances, grouped together as a single unit. You create a revision by creating a *revision block*. When you call ``save()`` on a registered model inside a revision block, it will be added to that revision.

.. code:: python

    # Declare a revision block.
    with reversion.create_revision():

        # Save a new model instance.
        obj = YourModel()
        obj.name = "obj v1"
        obj.save()

        # Store some meta-information.
        reversion.set_user(request.user)
        reversion.set_comment("Created revision 1")

    # Declare a new revision block.
    with reversion.create_revision():

        # Update the model instance.
        obj.name = "obj v2"
        obj.save()

        # Store some meta-information.
        reversion.set_user(request.user)
        reversion.set_comment("Created revision 2")

.. Important::

    Bulk actions, such as ``Queryset.update()``, do not send signals, so won't be noticed by django-reversion.


Loading revisions
^^^^^^^^^^^^^^^^^

Each model instance saved in a revision block is serialized as a :ref:`Version`. All versions in a revision block are associated with a single :ref:`Revision`.

You can load a :ref:`VersionQuerySet` of versions from the database. Versions are loaded with the most recent version first.

.. code:: python

    from reversion.models import Version

    # Load a queryset of versions for a specific model instance.
    versions = Version.objects.get_for_object(instance)
    assert len(versions) == 2

    # Check the serialized data for the first version.
    assert versions[1].field_dict["name"] == "obj v1"

    # Check the serialized data for the second version.
    assert versions[0].field_dict["name"] == "obj v2"


Revision metadata
^^^^^^^^^^^^^^^^^

:ref:`Revision` stores meta-information about the revision.

.. code:: python

    # Check the revision metadata for the first revision.
    assert versions[1].revision.comment == "Created revision 1"
    assert versions[1].revision.user == request.user
    assert isinstance(versions[1].revision.date_created, datetime.datetime)

    # Check the revision metadata for the second revision.
    assert versions[0].revision.comment == "Created revision 2"
    assert versions[0].revision.user == request.user
    assert isinstance(versions[0].revision.date_created, datetime.datetime)


Reverting revisions
^^^^^^^^^^^^^^^^^^^

Revert a :ref:`Revision` to restore the serialized model instances.

.. code:: python

    # Revert the first revision.
    versions[1].revision.revert()

    # Check the model instance has been reverted.
    obj.refresh_from_db()
    assert obj.name == "version 1"

    # Revert the second revision.
    versions[0].revision.revert()

    # Check the model instance has been reverted.
    obj.refresh_from_db()
    assert obj.name == "version 2"


Restoring deleted model instances
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Reverting a :ref:`Revision` will restore any serialized model instances that have been deleted.

.. code:: python

    # Delete the model instance, but store the pk.
    pk = obj.pk
    obj.delete()

    # Revert the second revision.
    versions[0].revision.revert()

    # Check the model has been restored to the database.
    obj = YourModel.objects.get(pk=obj.pk)
    assert obj.name == "version 2"


.. _registration-api:

Registration API
----------------

.. _register:

``reversion.register(model, **options)``

    Registers a model with django-reversion.

    Throws :ref:`RegistrationError` if the model has already been registered.

    ``model``
        The Django model to register.

    ``fields=None``
        An iterable of field names to include in the serialized data. If ``None``, all fields will be included.

    ``exclude=()``
        An iterable of field names to exclude from the serialized data.

    ``follow=()``
        An iterable of model relationships to follow when saving a version of this model. ``ForeignKey``, ``ManyToManyField`` and reversion ``ForeignKey`` relationships are supported. Any property that returns a ``Model`` or ``QuerySet`` is also supported.

    ``format="json"``
        The name of a Django serialization format to use when saving the model instance.

    ``for_concrete_model=True``
        If ``True`` proxy models will be saved under the same content type as their concrete model. If ``False``, proxy models will be saved under their own content type, effectively giving proxy models their own distinct history.

    ``ignore_duplicates=False``
        If ``True``, then an additional check is performed to avoid saving duplicate versions for this model.

        Checking for duplicate revisions adds significant overhead to the process of creating a revision. Don't enable it unless you really need it!

    ``use_natural_foreign_keys=False``
        If ``True``, the the model will be serialized using natural keys.

        See `Serialization of natural keys <https://docs.djangoproject.com/en/3.1/topics/serialization/#serialization-of-natural-keys>`_

    .. Hint::
        By default, django-reversion will not register any parent classes of a model that uses multi-table inheritance. If you wish to also add parent models to your revision, you must explicitly add their ``parent_ptr`` fields to the ``follow`` parameter when you register the model.

    .. include:: /_include/post-register.rst


``reversion.is_registered(model)``

    Returns whether the given model has been registered with django-reversion.

    ``model``
        The Django model to check.


``reversion.unregister(model)``

    Unregisters the given model from django-reversion.

    .. include:: /_include/throws-registration-error.rst

    ``model``
        The Django model to unregister.


``reversion.get_registered_models()``

    Returns an iterable of all registered models.


.. _revision-api:

Revision API
------------

``reversion.create_revision(manage_manually=False, using=None, atomic=True)``

    Marks a block of code as a *revision block*. Can also be used as a decorator.

    .. include:: /_include/create-revision-args.rst


``reversion.is_active()``

    Returns whether there is currently an active revision block.


``reversion.is_manage_manually()``

    Returns whether the current revision block is in ``manage_manually`` mode.


``reversion.set_user(user)``

    Sets the user for the current revision.

    .. include:: /_include/throws-revision-error.rst

    ``user``
        A ``User`` model instance (or whatever your ``settings.AUTH_USER_MODEL`` is).


``reversion.get_user()``

    Returns the user for the current revision.

    .. include:: /_include/throws-revision-error.rst


.. _set_comment:

``reversion.set_comment(comment)``

    Sets the comment for the current revision.

    .. include:: /_include/throws-revision-error.rst

    ``comment``
        The text comment for the revision.


``reversion.get_comment()``

    Returns the comment for the current revision.

    .. include:: /_include/throws-revision-error.rst


``reversion.set_date_created(date_created)``

    Sets the creation date for the current revision.

    .. include:: /_include/throws-revision-error.rst

    ``date_created``
        The creation date for the revision.


``reversion.get_date_created()``

    Returns the creation date for the current revision.

    .. include:: /_include/throws-revision-error.rst


``reversion.add_meta(model, **values)``

    Adds custom metadata to a revision.

    .. include:: /_include/throws-revision-error.rst

    ``model``
        A Django model to store the custom metadata. The model must have a ``ForeignKey`` or ``OneToOneField`` to :ref:`Revision`.

    ``**values``
        Values to be stored on ``model`` when it is saved.


``reversion.add_to_revision(obj, model_db=None)``

    Adds a model instance to a revision.

    .. include:: /_include/throws-revision-error.rst

    ``obj``
        A model instance to add to the revision.

    .. include:: /_include/model-db-arg.rst


.. _VersionQuerySet:

reversion.models.VersionQuerySet
--------------------------------

A ``QuerySet`` of :ref:`Version`. The results are ordered with the most recent :ref:`Version` first.


``Version.objects.get_for_model(model, model_db=None)``

    Returns a :ref:`VersionQuerySet` for the given model.

    .. include:: /_include/throws-registration-error.rst

    ``model``
        A registered model.

    .. include:: /_include/model-db-arg.rst


``Version.objects.get_for_object(obj, model_db=None)``

    Returns a :ref:`VersionQuerySet` for the given model instance.

    .. include:: /_include/throws-registration-error.rst

    ``obj``
        An instance of a registered model.

    .. include:: /_include/model-db-arg.rst


``Version.objects.get_for_object_reference(model, pk, model_db=None)``

    Returns a :ref:`VersionQuerySet` for the given model and primary key.

    .. include:: /_include/throws-registration-error.rst

    ``model``
        A registered model.

    ``pk``
        The database primary key of a model instance.

    .. include:: /_include/model-db-arg.rst


``Version.objects.get_deleted(model, model_db=None)``

    Returns a :ref:`VersionQuerySet` for the given model containing versions where the serialized model no longer exists in the database.

    .. include:: /_include/throws-registration-error.rst

    ``model``
        A registered model.

    ``db``
        The database to load the versions from.

    .. include:: /_include/model-db-arg.rst


``Version.objects.get_unique()``

    Returns an iterable of :ref:`Version`, where each version is unique for a given database, model instance, and set of serialized fields.


.. _Version:

reversion.models.Version
------------------------

Represents a single model instance serialized in a revision.


``Version.id``

    The database primary key of the :ref:`Version`.


``Version.revision``

    A ``ForeignKey`` to a :ref:`Revision` instance.


``Version.content_type``

    The ``ContentType`` of the serialized model instance.


``Version.object_id``

    The string representation of the serialized model instance's primary key.


``Version.db``

    The Django database alias where the serialized model was saved.


``Version.format``

    The name of the Django serialization format used to serialize the model instance.


``Version.serialized_data``

    The raw serialized data of the model instance.


``Version.object_repr``

    The stored snapshot of the model instance's ``__str__`` method when the instance was serialized.


``Version.field_dict``

    A dictionary of stored model fields. This includes fields from any parent models in the same revision.

    .. include:: /_include/throws-revert-error.rst


``Version.revert()``

    Restores the serialized model instance to the database. To restore the entire revision, use :ref:`Revision.revert() <Revision-revert>`.

    .. include:: /_include/throws-revert-error.rst


.. _Revision:

reversion.models.Revision
-------------------------

Contains metadata about a revision, and groups together all :ref:`Version` instances created in that revision.

``Revision.id``

    The database primary key of the :ref:`Revision`.


``Revision.date_created``

    A ``datetime`` when the revision was created.


``Revision.user``

    The ``User`` that created the revision, or None.


``Revision.get_comment()``

    A text comment on the revision.


.. _Revision-revert:

``Revision.revert(delete=False)``

    Restores all contained serialized model instances to the database.

    .. include:: /_include/throws-revert-error.rst

    ``delete``
        If ``True``, any model instances which have been created and are reachable by the ``follow`` clause of any model instances in this revision will be deleted. This effectively restores a group of related models to the state they were in when the revision was created.