Django Admin: Detect if a subset of an object fields has changed and which of them

django, django-admin, django-forms, django-models

Solution

Modifying the answer above... taking the brilliant function from Dominik Szopa and changing it will solve your relationship change detection: Use this:

def get_changes_between_models(model1, model2, excludes = []):
    changes = {}
    for field in model1._meta.fields:
        if not (field.name in excludes):
            if field.value_from_object(model1) != field.value_from_object(model2):
                changes[field.verbose_name] = (field.value_from_object(model1),
                                                   field.value_from_object(model2))
    return changes

Then in your code you can say (avoid try/except for performance reasons):

if (self.id):
    old = MyModel.Objects.get(pk=self.id)
    changes = get_changes_between_models(self, old)

    if (changes):
        # Process based on what is changed.

If you are doing this at the "model" level, there is no way to save the extra query. The data has already been changed by the time you reach the "Save" point. My first post, so forgive me if I sound like an idiot.

Problem

I need to detect when some of the fields of certain model have changed in the admin, to later send notifications depending on which fields changed and previous/current values of those fields. I tried using a `ModelForm` and overriding the `save()` method, but the form's `self.cleaned_data` and `seld.instance` already have the new values of the fields.

Original source