我需要检测管理员中某些模型的某些字段何时发生更改,以便稍后根据更改的字段和这些字段的上一个/当前值发送通知。
我尝试使用ModelForm
并覆盖save()
方法,但表单self.cleaned_data
和seld.instance
已经包含了字段的新值。
答案 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。它与模型实例进行比较并返回更改字典。