4

There are several models in my django app. Some of them derive from models.Model, some - from django-hvad's translatable model. I want to log every save/delete/update operation on them. I am aware of standard django logger of admin actions, but they are too brief and non-verbose to satisfy my needs.

Generally speaking, one common way to achieve this is to define super-class with these operations and extend each model from it. This is not my case because some of my models are translatable and some are not.

Second way are aspects/decorators. I guess, python/django must have something like that, but I don't know what exactly :)

Please, provide me with the most suitable way to do this logging. Thanks!

Vitaly Trifanov
  • 631
  • 2
  • 8
  • 17

1 Answers1

5

You could write a mixin for your model.

import logging

class LogOnUpdateDeleteMixin(models.Model):
    pass

    def delete(self, *args, **kwargs):
        super(LogOnUpdateDeleteMixin, self).delete(*args, **kwargs)
        logging.info("%s instance %s (pk %s) deleted" % (str(self._meta), str(self), str(self.pk),) # or whatever you like

    def save(self, *args, **kwargs):
        super(LogOnUpdateDeleteMixin, self).save(*args, **kwargs)
        logging.info("%s instance %s (pk %s) updated" % (str(self._meta), str(self), str(self.pk),) # or whatever you like

class Meta:
    abstract = True

Now just use it in your model.

class MyModel(LogOnUpdateDeleteMixin, models.Model):
    ...
    # Update/Delete actions will write to log. Re-use your mixin as needed in as many models as needed.

You can re-use this mixin again and again. Perform translation as you wish, set some attributes in your models and check for them in the mixin.

Ian Price
  • 7,416
  • 2
  • 23
  • 34
  • Ian, thanks for answer and code examples! I've searched a little bit and found [SOW question about mixins](http://stackoverflow.com/questions/533631/what-is-a-mixin-and-why-are-they-useful) that confirms your answer and concludes that mixins are suited exactly for issues like the mine one. – Vitaly Trifanov Jun 26 '16 at 22:39
  • Glad it helped! If you wrote a generic way to tell whether or not a model is translatable and acted accordingly, I think you'd be set. Django's source code makes beautiful use of mixins/inheritance and is worth delving in to for that reason alone :) – Ian Price Jun 26 '16 at 23:04
  • 1
    Hi @IanPrice! sorry for necroposting, but unfortunately your solution works for me just partially -- the `delete` hook doesn't work at all, when I delete an instance from admin page. It just doesn't even enters that method :( though save does work – AlexNikolaev94 Jul 26 '18 at 20:36
  • Ad Alex, that because the delete method is not used on queries (https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods) You can solve that problem by using signals – Jasper Aug 08 '18 at 13:49