在你需要旧值的.save()中修改字段的django中最好/最合适的习惯用法是什么?

时间:2010-04-16 16:15:36

标签: django orm signals models

说我有:

class LogModel(models.Model):
    message = models.CharField(max_length=512)

class Assignment(models.Model):
    someperson = models.ForeignKey(SomeOtherModel)
    def save(self, *args, **kwargs):
        super(Assignment, self).save()
        old_person = #?????
        LogModel(message="%s is no longer assigned to %s"%(old_person, self).save()
        LogModel(message="%s is now assigned to %s"%(self.someperson, self).save()

我的目标是将一些有关分配给谁的消息保存到LogModel。请注意,我需要知道此字段的旧的预设值。

我看过代码,建议在super()。save()之前,通过主键从数据库中检索实例并从那里获取旧值。这可能有用,但有点乱。

此外,我计划最终通过信号 - 即pre_save()和post_save()将此代码从.save()方法中分离出来。尝试使用上面的逻辑(在pre_save中从db中检索,在post_save中创建日志条目)似乎在这里失败,因为pre_save和post_save是两个单独的方法。也许在pre_save中我可以检索旧值并将其作为属性粘贴在模型上?

我想知道是否有一个共同的习惯用法。感谢。

3 个答案:

答案 0 :(得分:1)

几个月前,我在网上找到了一个很好的办法...

class YourModel(models.Model):

    def __init__(self, *args, **kwargs):
        super(YourModel, self).__init__(*args, **kwargs)
        self.original = {}
        id = getattr(self, 'id', None)

        for field in self._meta.fields:
            if id:
                self.original[field.name] = getattr(self, field.name, None)
            else:
                self.original[field.name] = None

基本上,模型字段的副本将保存到self.original。然后,您可以在模型的其他位置访问它...

def save(self, *args, **kwargs):
    if self.original['my_property'] != self.my_property:
        # ...

答案 1 :(得分:0)

可以使用signals轻松完成。每个Django模型都有pre-savepost-save信号。

答案 2 :(得分:0)

所以我想出了这个:

class LogModel(models.Model):
    message = models.CharField(max_length=512)

class Assignment(models.Model):
    someperson = models.ForeignKey(SomeOtherModel)

import weakref
_save_magic = weakref.WeakKeyDictionary()

@connect(pre_save, Assignment)
def Assignment_presave(sender, instance, **kwargs):
    if instance.pk:
        _save_magic[instance] = Assignment.objects.get(pk=instance.pk).someperson

@connect(post_save, Assignment)
def Assignment_postsave(sender, instance, **kwargs):
    old = None
    if instance in _save_magic:
        old = _save_magic[instance]
        del _save_magic[instance]
        LogModel(message="%s is no longer assigned to %s"%(old, self).save()
    LogModel(message="%s is now assigned to %s"%(instance.someperson, self).save()

StackOverflow的想法是什么?还有什么更好的?有什么提示吗?