1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
from django.forms.models import model_to_dict
import django.db.models.fields.related
class DiffableModel(object):
"""
Make it possible to diff a model.
"""
def __init__(self, *args, **kwargs):
super(DiffableModel, self).__init__(*args, **kwargs)
self.__initial = self._dict
@property
def diff(self):
manytomanyfieldnames = [f.name for f in self._meta.many_to_many]
d1 = self.__initial
d2 = self._dict
diffs = dict([(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]])
# Foreign key lookups
for k,v in diffs.items():
if type(self._meta.get_field(k)) is django.db.models.fields.related.ForeignKey:
# If it's a foreign key, look up the name again on ourselves.
# Since we only care about the *new* value, it's easy enough.
diffs[k] = (v[0], getattr(self, k))
# Many to many lookups
if hasattr(self, 'map_manytomany_for_diff'):
for k,v in diffs.items():
if k in manytomanyfieldnames and self.map_manytomany_for_diff.has_key(k):
# Try to show the display name instead here
newvalue = getattr(self, self.map_manytomany_for_diff[k])
diffs[k] = (v[0], newvalue)
return diffs
def save(self, *args, **kwargs):
super(DiffableModel, self).save(*args, **kwargs)
self.__initial = self._dict
@property
def _dict(self):
fields = [field.name for field in self._meta.fields]
fields.extend([field.name for field in self._meta.many_to_many])
return model_to_dict(self, fields=fields)
|