14

谢谢你的时间。

我在 Django 1.4 上,我有以下代码:它是我Quest模型的覆盖保存方法。

@commit_on_success
def save(self, *args, **kwargs):
    from ib.quest.models.quest_status_update import QuestStatusUpdate
    created = not self.pk

    if not created:
        quest = Quest.objects.get(pk=self)
        # CHECK FOR SOME OLD VALUE
    super(Quest, self).save(*args, **kwargs)

我找不到这样做的聪明方法。对我来说,为了找出旧的实例值而必须对我当前正在更新的对象进行新的查询似乎很愚蠢。

有一个更好的方法吗?

谢谢你们。

弗朗西斯科

4

3 回答 3

18

您可以将旧值存储在 init 方法中:

def __init__(self, *args, **kwargs):
    super(MyModel, self).__init__(*args, **kwargs)
    self.old_my_field = self.my_field

def save(self, *args, **kwargs):
    print self.old_my_field
    print self.my_field

您可能可以使用 deepcopy 或类似的东西来复制整个对象,以便以后在保存和删除方法中使用。

于 2014-10-17T18:25:15.750 回答
10

Django 不会缓存模型实例的旧值,因此您需要自己执行此操作或在保存之前执行另一个查询。

一种常见的模式是使用预保存信号(或将此代码直接放在您的 save() 方法中,就像您所做的那样):

old_instance = MyModel.objects.get(pk=instance.pk)
# compare instance with old_instance, and maybe decide whether to continue

如果您想保留旧值的缓存,那么您可能会在您的视图代码中这样做:

from copy import deepcopy
object = MyModel.objects.get(pk=some_value)
cache = deepcopy(object)

# Do something with object, and then compare with cache before saving

最近也有关于 django-developers 的讨论,以及其他一些可能的解决方案。

于 2012-10-18T17:59:19.607 回答
1

I am checking the difference to old values using a django-reversion signal, but the same logic would apply to the save signals. The difference for me being that I want to save whether the field was saved or not.

@receiver(reversion.pre_revision_commit)
def it_worked(sender, **kwargs):
    currentVersion = kwargs.pop('versions')[0].field_dict
    fieldList = currentVersion.keys()
    fieldList.remove('id')
    commentDict = {}
    print fieldList
    try:
        pastVersion = reversion.get_for_object(kwargs.pop('instances')[0])[0].field_dict
    except IndexError:
        for field in fieldList:
            commentDict[field] = "Created"
        comment = commentDict
    except TypeError:
        for field in fieldList:
            commentDict[field] = "Deleted"
        comment = commentDict
    else:
        for field in fieldList:
            try:
                pastTest = pastVersion[field]
            except KeyError:
                commentDict[field] = "Created"
            else:       
                if currentVersion[field] != pastTest:
                    commentDict[field] = "Changed"
                else:
                    commentDict[field] = "Unchanged"
        comment = commentDict
    revision = kwargs.pop('revision')
    revision.comment = comment
    revision.save()
    kwargs['revision'] = revision
    sender.save_revision
于 2012-10-18T18:27:33.893 回答