Ticket #11007: model-instance-changes-v2.patch

File model-instance-changes-v2.patch, 2.7 KB (added by Dennis Kaarsemaker, 15 years ago)

Better patch with docs and tests

  • tests/modeltests/changes/__init__.py

     
     1
  • tests/modeltests/changes/models.py

     
     1"""
     2Detecting changes to an object
     3
     4The ``changes`` method of the django.models.Model class returns a dict
     5{attribute: (old_value, new_value)} for all changed fields in a
     6model instance.
     7"""
     8
     9from django.db import models
     10
     11class Person(models.Model):
     12    name = models.CharField(max_length=20)
     13    job = models.CharField(max_length=30)
     14
     15    def __unicode__(self):
     16        return self.name
     17
     18__test__ = {'API_TESTS':"""
     19>>> a = Person(name=u'Adrian', job=u'Hacker')
     20>>> a.changes()
     21{'job': (None, u'Hacker'), 'name': (None, u'Adrian')}
     22>>> a.save()
     23>>> a.changes()
     24{}
     25>>> a.name = u'Adrian H.'
     26>>> a.changes()
     27{'name': (u'Adrian', u'Adrian H.')}
     28"""}
  • django/db/models/base.py

     
    606606    def prepare_database_save(self, unused):
    607607        return self.pk
    608608
     609    def changes(self):
     610        fields = [x.name for x in self._meta._fields() if not (x.name.endswith('_ptr_id') or x.name.endswith('_ptr'))]
     611        if not self.pk:
     612            return dict([(x, (None, getattr(self, x))) for x in fields if getattr(self,x) is not None])
     613        old = self.__class__.objects.get(pk=self.pk)
     614        return dict([(x, (getattr(old, x), getattr(self, x))) for x in fields if getattr(self, x) != getattr(old, x)])
     615         
    609616
    610617############################################
    611618# HELPER FUNCTIONS (CURRIED MODEL METHODS) #
  • docs/ref/models/instances.txt

     
    200200   For more details, including how to delete objects in bulk, see
    201201   :ref:`topics-db-queries-delete`.
    202202
     203Changes to objects
     204==================
     205
     206.. method:: Model.changes()
     207
     208Return a dict {atrribute_name: (old_value, new_value)} containing all
     209attributes of the object that differ from the values stored in the database.
     210For instances that have not yet been saved, all attributes with a value other
     211than None are included and the old_value is set to None.
     212
    203213.. _model-instance-methods:
    204214
    205215Other model instance methods
Back to Top