Skip to content

Latest commit

 

History

History
489 lines (260 loc) · 12.9 KB

File metadata and controls

489 lines (260 loc) · 12.9 KB

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.

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.

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.

# 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.

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.

# 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.

# 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.

# 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

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

object_id_field=None

The name of the model field to use as the version's object_id. Defaults to the model's primary key field. Use this when you want versions to be keyed on a different unique field, such as a slug.

The field must exist on the model (validated at registration time). "pk" is not a valid value — use the concrete field name instead (e.g. "id").

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.

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.

model
The Django model to unregister.

reversion.get_registered_models()

Returns an iterable of all registered models.

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.

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.

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

reversion.get_user()

Returns the user for the current revision.

reversion.set_comment(comment)

Sets the comment for the current revision.

comment
The text comment for the revision.

reversion.get_comment()

Returns the comment for the current revision.

reversion.set_date_created(date_created)

Sets the creation date for the current revision.

date_created
The creation date for the revision.

reversion.get_date_created()

Returns the creation date for the current revision.

reversion.add_meta(model, **values)

Adds custom metadata to a revision.

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.

obj
A model instance to add to the revision.

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.

model
A registered model.

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

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

obj
An instance of a registered model.

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

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

model
A registered model.
pk
The database primary key of a model instance.

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.

model
A registered model.
db
The database to load the versions from.

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.

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.

Version.revert()

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

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(delete=False)

Restores all contained serialized model instances to the database.

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.