Сравните старые и обновленные поля в модели Django - PullRequest
1 голос
/ 09 декабря 2011

Я хочу сравнить старое и обновленное поле в модели.Я сделал эту проблему для одного поля, но я хочу сделать это для всех полей:

class MyUser(User)
    def save(self, **kwargs):
       if self.pk is not None:
         orig = MyUser.objects.get(pk=self.pk)
         orig_field_names = orig._meta.get_all_field_names()
         field_names = self._meta.get_all_field_names()
         # I want do this in loop 
         if orig.first_name != self.first_name:
           print 'first_name changed'
           UpdateLog.objects.create(
                user = orig,
                filed_name = self.first_name,
                update_time = datetime.now()
             )
         super(MyUser, self).save(**kwargs)

Заранее спасибо

Ответы [ 3 ]

3 голосов
/ 09 декабря 2011

Вот моя функция для сравнения полей. Становится немного волосатым, когда имеешь дело с внешними ключами, но в целом это не так уж плохо:

def get_changes_between_objects(object1, object2, excludes=[]):
    """
    Finds the changes between the common fields on two objects

    :param object1: The first object
    :param object2: The second object
    :param excludes: A list of field names to exclude
    """
    changes = {}

    # For every field in the model
    for field in object1._meta.fields:
        # Don't process excluded fields or automatically updating fields
        if not field.name in excludes and not isinstance(field, fields.AutoField):
            # If the field isn't a related field (i.e. a foreign key)..
            if not isinstance(field, fields.related.RelatedField):
                old_val = field.value_from_object(object1)
                new_val = field.value_from_object(object2)
                # If the old value doesn't equal the new value, and they're
                # not both equivalent to null (i.e. None and "")
                if old_val != new_val and not(not old_val and not new_val):
                    changes[field.verbose_name] = (old_val, new_val)

            # If the field is a related field..
            elif isinstance(field, fields.related.RelatedField):
                if field.value_from_object(object1) != field.value_from_object(object2):
                    old_pk = field.value_from_object(object1)
                    try:
                        old_val = field.related.parent_model.objects.get(pk=old_pk)
                    except field.related.parent_model.DoesNotExist:
                        old_val = None

                    new_pk = field.value_from_object(object2)
                    try:
                        new_val = field.related.parent_model.objects.get(pk=new_pk)
                    except field.related.parent_model.DoesNotExist:
                        new_val = None

                    changes[field.verbose_name] = (old_val, new_val)

    return changes

Использование:

>>> item = Item.objects.get(pk=1)
>>> item_old = Item.objects.get(pk=1)
>>> print item.my_attribute
'foo'
>>> item.my_attribute = 'bar'
>>> get_changes_between_objects(item, item_old)
{'My Attribute': ('bar', 'foo')}
2 голосов
/ 09 декабря 2011

Вы хотите сигнал

0 голосов
/ 09 декабря 2011

Прочитайте документы до голосования -1. Поймай сигнал - лучший способ сделать это

...