17

I am working on a Django + DRF Web Application and I want to track changes to all model instances in the Database and keep a log of all changes made, namely:

TABLE - Table to which record was added/modified
FIELD - Field that was modified.
PK_RECORD - Primary Key of the model instance that was modified.
OLD_VAL - Old Value of the field.
NEW_VAL - New Value of the field.
CHANGED_ON - Date it was changed on.
CHANGED_BY - Who changed it?
REVISION_ID - Revision ID of the current Model Instance.

Later on, I want the user to be able to track the changes made to the model and see which version of the instance was used for a particular action so everything can be tracked.

For this purpose, I tried to understand the various packages in django for tracking database model changes, some of them listed here:

django-model-audit packages

I tried django-reversion, django-simple-history, django-audit-log, django-historicalrecords, but I fail to understand how and why I should use each of these packages as some of them seem like an overkill for the requirements. So, after two days of searching and reading through numerous posts about how I should be tracking model changes, I have basically done nothing.

I am new to Django and would appreciate any help.

If something is not clear, feel free to comment your queries. Thanks in advance :)

Divij Sehgal
  • 647
  • 2
  • 11
  • 26
  • Did you also implemented tracking changes to reverse related field changes? Could you please provide gist or repository link? I will implement the same approaches. – khashashin Jul 21 '19 at 06:04
  • Hey.. sorry that's more than two years old. I don't completely remember how I did it. I think we kept a record of the changes as what key and value was changed on what record in which table on what date. We only kept the new value and the old value for that record and used a JSON Field for that. Since various fields can have various types, we decided to save changes made as a {key:pair} in JSONObject in the changes table. Does that make sense? Or message me if it doesn't. – Divij Sehgal Jul 21 '19 at 11:31

1 Answers1

15

Have you explored on django signals pre_save?https://docs.djangoproject.com/en/dev/topics/signals/

from django.db.models.signals import pre_save          
from django.dispatch import receiver
from myapp.models import MyModel

@receiver(pre_save, sender=MyModel)
def my_handler(sender, instance=None, **kwargs):
    # instance variable will have the record which is about to be saved. 
    # So log your details accordingly.
Saransh Singh
  • 730
  • 4
  • 11
Abijith Mg
  • 2,647
  • 21
  • 35
  • 8
    Beware though that signals are not triggered for bulk actions, so these changes would not be recorded. – Thierry J. Mar 20 '19 at 12:23
  • @ThierryJ. what is a bulk action? Can you give an example? – Engin Yapici Sep 27 '19 at 20:31
  • 2
    `MyModel.objects.bulk_create(my_model1, my_model2)`. This will create all the `MyModel` instances given in arguments. But this will create them all at once, using a single database query. This action will not trigger any signal. The function `bulk_update` works similarly. See https://docs.djangoproject.com/en/2.2/ref/models/querysets/#bulk-create for more details. – Thierry J. Sep 28 '19 at 21:14
  • 1
    But logging changes here will be executed no matter of save was success or not - if we will have IntegrityError, handler will save logs anyway - but it is not correct:save was not succeeded. – Kasikn77 Jan 08 '21 at 10:34