保存时检查以前的型号值

时间:2014-09-03 14:52:42

标签: django django-models django-signals

我有一个保存游览的模型。用户可以改变这次短途旅行,但我需要知道这次短途旅行之前的变化,因为我会记录每次短途旅行的“预订”次数,如果你改变了短途旅行,我需要删除一次预订。以前的游览。

我不完全确定应该怎么做。

我猜你用这个信号了吗?

我应该使用pre_save,pre_init还是最适合的?

pre_save看起来不正确,因为它会打印新值,而不是我预期的“旧值”

@receiver(pre_save, sender=Delegate)
def my_callback(sender, instance, *args, **kwargs):
    print instance.excursion

3 个答案:

答案 0 :(得分:7)

你有几种选择。

首先是覆盖保存方法

#Delegate
def save(self, *args, **kwargs):
    if self.pk:
        previous_excursion = Delegate.objects.get(self.pk).excursion
    super(Model, self).save(*args, **kwargs)
    if self.pk and self.excursion != previous_excursion:
        #change booking

第二个是绑定功能以发布保存信号+ django model utils field tracker

@receiver(post_save, sender=Delegate)
def create_change_booking(sender,instance, signal, created, **kwargs):
    if created:
        previous_excursion = get it from django model utils field tracker
        #change booking

当你正在运行时,另一个解决方案是 pre_save

@receiver(pre_save, sender=Delegate)
def my_callback(sender, instance, *args, **kwargs):
    previous_excursion = Delegate.objects.get(self.pk).excursion
    if instance.pk and instance.excursion != previous_excursion:
        #change booking  

答案 1 :(得分:1)

作为替代方案,如果您使用的是Django表单:

您实例的待版本存储在模型的Django表单的form.instance中。在保存时,将运行验证,并将此新版本应用于模型,然后保存模型。

这意味着您可以通过将form.instance与当前模型进行比较来检查新版本与旧版本之间的差异。

调用Django Admin的save_model方法时会发生这种情况。 (见contrib / admin / options.py)

如果你可以使用Django表格,这是最古老的方式,我会说。

这是使用Django表单处理数据更改的关键:

form = ModelForm(request.POST, request.FILES, instance=obj)
new_object = form.instance  # not saved yet
# changes are stored in form.changed_data
new_saved_object = form.save()

form.changed_data将包含已更改的字段,这意味着如果没有更改,则该字段为空。

答案 2 :(得分:0)

您可以使用Django模型工具来跟踪Django模型字段。检查这个例子。

pip install django-model-utils

然后,您可以定义模型并在模型中使用fieldtracker。

from django.db import models
from model_utils import FieldTracker

class Post(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()
    tracker = FieldTracker()
    status = models.CharField(choices=STATUS, default=STATUS.draft, max_length=20)

保存后,您可以这样使用:

@receiver(post_save, sender=Post) 
def my_callback(sender, instance,*args, **kwargs):
    print (instance.title)
    print (instance.tracker.previous('title'))
    print (instance.status)
    print (instance.tracker.previous('status'))

这将帮助您做很多有关状态更改的活动。因为覆盖保存方法不是一个好主意。