Is there a way to access a django-reversion object as if it were the current object?

3k views Asked by At

I'm using Django-Reversion - is there a way to temporarily re-instate a previous version of an object so that it can be viewed in a DetailView?

Non working code - version.get_object() would be nice..

class ProductDetailView(DetailView):

    def get_object(self):
        obj = super(ProductDetailView, self).get_object()
        if self.request.GET.get('v') is not None:
            version_id = force_text(self.request.GET.get('v'))
            version = get_object_or_404(Version, pk=version_id, object_id=force_text(obj.pk))
            return version.get_object()
        return obj
2

There are 2 answers

3
Serafeim On BEST ANSWER

Copying from my post @ http://spapas.github.io/2015/01/21/django-model-auditing/#using-django-reversion

[...] each version has a revision attribute for the corresponding revision and can be used to do the following:

  • get the user that made the change through the revision.user attribute
  • get the date of the change through the revision.date_created attribute
  • get the values of the object fields as they were in this revision using the field_dict attribute
  • get a model instance as it was on that revision using the object_version.object attribute
  • revert to that previous version of that object using the revert() method

So try changing your return version.get_object() line to return version.object_version.object!

Update to answer OP's comment for related objects: django-reversion supports revisions that group changes to models -- copying from http://django-reversion.readthedocs.org/en/latest/api.html#creating-revisions

A revision represents one or more changes made to your models, grouped together as a single unit. You create a revision by marking up a section of code to represent a revision. Whenever you call save() on a model within the scope of a revision, it will be added to that revision.

So, if you change all your models in a single POST request you can add it in a revision to make all your changed objects members of that revision. After that, when you have a version of the object you can use its reversion to get all the versions of all objects that belong to the same revision: version.revision.version_set.all().

If you don't actually save the related objects when you save the main object so the related objects don't belong to the revision, then yes, you need to go down the rabbit hole and get the revisions of the related objects as they were on the date of the main object revision (this is a rather complex query).

0
Victor Borràs On

I guess your problem is solved, but just for the record, you can access the instance using version._object_version.object, but it will have the reverse relation info from the latest version.

It seems like the only way to get the complete instance including the relation data is to start a transaction, revert the revision, do whatever you need to do and undo the transaction, as stated by the author here: https://groups.google.com/d/msg/django-reversion/FIi8smbLGEc/BvLN20p4HAAJ.