1

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
Guy Bowden
  • 4,997
  • 5
  • 38
  • 58

2 Answers2

3

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.

1

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

Serafeim
  • 14,962
  • 14
  • 91
  • 133
  • Nice one - thanks.. now how would I fetch the same version of the related objects? I think I could be heading down a rabbit hole now.. – Guy Bowden Jun 11 '15 at 10:01
  • Actually django-reversion has this already supported (!) through the revision concept: http://django-reversion.readthedocs.org/en/latest/api.html#creating-revisions -- I'll update my answer with a little bit more info – Serafeim Jun 11 '15 at 11:37
  • Thanks Serafeim! In my case, version.revision.version_set.all() gives both the new manytomany choices as well as the old ones! I am unsure how to get the right one here. – Wim Feijen Apr 28 '17 at 14:38