Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging item value changes to Django objects [duplicate]

At the moment I'm thinking on how best to implement logging of changes on a Model so as to provide some form of audit trail for the object.

I've looked into django-reversion and to a certain extent it does what I need it to do, however my needs are more simpler than that. I just want something that is able to record which user changed what field on an object when, as well as the previous value of the field before the change was committed.

A simple class to store this would be something like:

class AuditLogEntry(models.Model):
    user = ForeignKey(User, verbose_name=_(u"user"), related_name="actions")
    obj = ForeignKey(ModelToLog, verbose_name=_(u"Model"), related_name="history")
    timestamp = DateTimeField(default=datetime.now)
    field = models.CharField(max_length=64)
    value = models.CharField(max_length=256)

At the moment I am thinking of simply adding a block of code in the view handler that updates the model with something like this:

form = ModelToLogForm(request.POST, instance=obj)
prev_data = dict()
for changed_field in form.changed_data:
    prev_data[changed_field] = form.instance.get_attribute(changed_field)
if form.is_valid():
    form.save()
    for changed_field in keys(prev_data):
        obj.history.create(user=request.user, obj=obj, field=changed_field, value=prev_data[changed_field]

In theory, it should work, however I keep having the nudging sense that this is not the best way to do it. Is there a better way to do something like this?

like image 503
wshyang Avatar asked Nov 05 '22 05:11

wshyang


1 Answers

There's a small problem with your approach. What happens if the model is changed from elsewhere in the code? You don't want to splatter this history tracking code everywhere. Investigate signals, which is what the django admin history solution uses as mentioned by zobbo.

like image 181
Josh Smeaton Avatar answered Nov 09 '22 03:11

Josh Smeaton