Django Admin:检测对象字段的子集是否已更改以及哪些更改

时间:2010-03-08 01:59:38

标签: django django-models django-admin django-forms

我需要检测管理员中某些模型的某些字段何时发生更改,以便稍后根据更改的字段和这些字段的上一个/当前值发送通知。

我尝试使用ModelForm并覆盖save()方法,但表单self.cleaned_dataseld.instance已经包含了字段的新值。

3 个答案:

答案 0 :(得分:7)

为了避免额外的数据库查找,我修改了构造函数以记住初始值,并在以后的save方法中使用它:

class Package(models.Model):
    feedback = models.IntegerField(default = 0, choices = FEEDBACK_CHOICES)
    feedback_time = models.DateTimeField(null = True)

    def __init__(self, *args, **kw):
        super(Package, self).__init__(*args, **kw)
        self._old_feedback = self.feedback

    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        if not force_insert and self.feedback != self._old_feedback:
            self.feedback_time = datetime.utcnow()
        return super(Package, self).save(force_insert, force_update, *args, **kwargs)

答案 1 :(得分:7)

修改上面的答案......从Dominik Szopa获取精彩的功能并更改它将解决您的关系变化检测:使用此:

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

然后在你的代码中你可以说(避免尝试/除了性能原因):

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.

如果您在“模型”级别执行此操作,则无法保存额外查询。到达“保存”点时,数据已经更改。我的第一篇文章,请原谅我,如果我听起来像个白痴。

答案 2 :(得分:1)

为了获得两个模型实例的差异,您还可以使用此function。它与模型实例进行比较并返回更改字典。