【发布时间】:2010-01-08 18:37:49
【问题描述】:
有几次我遇到过这样的情况,在节省时间时我需要知道哪些模型字段将被更新并采取相应的行动。
对此最明显的解决方案是获取主键字段并从数据库中检索模型的副本:
class MyModel(models.Model):
def save(self, force_insert=False, force_update=False, using=None):
if self.id is not None:
unsaved_copy = MyModel.objects.get(id=self.id)
# Do your comparisons here
super(MyModel, self).save(force_insert, force_update, using)
这工作得很好,但是,它会针对您正在保存的模型的每个实例访问数据库(如果您要进行大量此类保存,可能会很不方便)。
很明显,如果可以“记住”模型实例生命周期开始时的旧字段值(__init__),则不需要从数据库中检索模型的副本。所以我想出了这个小技巧:
class MyModel(models.Model):
def __init__(self, *args, **kwargs):
super(MyModel, self).__init__(*args, **kwargs)
self.unsaved = {}
for field in self._meta.fields:
self.unsaved[field.name] = getattr(self, field.name, None)
def save(self, force_insert=False, force_update=False, using=None):
for name, value in self.unsaved.iteritems():
print "Field:%s Old:%s New:%s" % (name, value, getattr(self, name, None))
# old values can be accessed through the self.unsaved member
super(MyModel, self).save(force_insert, force_update, using)
这似乎可行,但它使用了django.db.models.Model 的非公共接口。
也许有人知道一种更清洁的方法?
【问题讨论】:
标签: python django django-models