1

I have a function to display history list of version objects as below and I have this particular .py file in public repo at https://github.com/praneethkumarpidugu/django-reversion/blob/master/rev_history/views.py#L1:

from django.http import HttpResponse
from reversion.models import Version
#from django.contrib.admin.models import LogEntry
import json

def history_list(request):
    history_list = Version.objects.all().order_by('-revision__date_created')

    data = []

    for i in history_list:
        data.append({
            'date_time': str(i.revision.date_created),
            'user': str(i.revision.user),
            'object': i.object_repr,
            'type': i.content_type.name,
            'comment': i.revision.comment
        })

    data_ser = json.dumps(data)
    return HttpResponse(data_ser, content_type="application/json")

To change the object entities I visited admin page 127.0.0.1:8000/admin I changed a boolean field for representation say "is_active" from true to false.

Now, I come to history page 127.0.0.1:8000/history

I see the json data as below:

{"type": "model a", "date_time": "2015-03-04 15:58:36.141569+00:00", **"comment": "Changed is_active."**, "object": "ModelA object", "user": "admin1"}

Solution likely to have: I want comment to be split as previous_value: "True", "new_value": "False", "field": "is_active".

my research driving towards solution I digged into Revision class of reversion/models.py to see if there are any extra arguements to display field and value but to my understanding I'm unable to find the clue where I could find field and values for comment. for reference here is the comment from Revision

comment = models.TextField(blank=True,
                               verbose_name=_("comment"),
                               help_text="A text comment on this revision.")

solution to represent field : This might look a bit silly but I just hacked into my own data of comment above to represent field as

  'field': i.revision.comment.split(' ')[-1] 

But I still need to get the values of the field which are original and new values after changing.

Vini.g.fer
  • 11,639
  • 16
  • 61
  • 90
Praneeth
  • 902
  • 2
  • 11
  • 25

2 Answers2

1

I think that if you save the ver.field_dict of the actual and the previous (the same place where you make the version commit), compare then and save the version changes in another Model you can achieve what you want.

history_list = Version.objects.all().order_by('-revision__date_created')
ver = history_list[0]
ver.field_dict

Maybe this app can help you. https://github.com/jedie/django-reversion-compare

Arthur Alvim
  • 1,044
  • 12
  • 23
1

I hope I understood the problem properly, here's the half baked solution to it:

from django.db.models.signals import pre_save
from django.dispatch import receiver
import reversion

@receiver(pre_save)
def _pre_save(sender, **kwargs):
    _i = kwargs.get('instance')
    _i_old = sender.objects.get(pk=_i.pk)
    _current, _past = set(_i.__dict__.keys()), set(_i_old.__dict__.keys())
    _intersection = _current.intersection(_past)
    _changed_keys = set(o for o in _intersection if _i.__dict__[o] != _i_old.__dict__[o])
    _comment = ['changed {} from {} to {}'.format(_, _i_old.__dict__[_], _i.__dict__[_]) for _ in _changed_keys]
    reversion.set_comment(', '.join(_comment))

Haven't thought much about the performance overhead, but this should do the trick.

Hope this helps.

Ankit Popli
  • 2,809
  • 3
  • 37
  • 61
  • where should this function go ? – Hakim May 02 '16 at 02:15
  • This is a [signal](https://docs.djangoproject.com/en/1.9/topics/signals/). Register it once in your django app. – Ankit Popli May 02 '16 at 05:55
  • Unfortunately, it's not working anymore. reversion.set_comment(', '.join(_comment)) raises an error module does not have a method set_comment – Hakim May 02 '16 at 05:57
  • make sure you are not overriding 'reversion' variable anywhere! Its still [there](https://github.com/etianen/django-reversion/blob/4a7031dde7266c1adf8efb13d73fc7fc5beb49cf/src/reversion/revisions.py#L228) – Ankit Popli May 02 '16 at 06:19
  • i copied your answer into a new signals.py and imported signals.py in models.py, plus if i deleted the last line (that causes the error) i'll get a recursion error. – Hakim May 02 '16 at 06:21
  • Please follow this [doc](https://django-reversion.readthedocs.io/en/latest/) to make sure everything is in place. – Ankit Popli May 02 '16 at 06:24