【问题标题】:Check previous model value on save保存时检查以前的模型值
【发布时间】:2014-10-28 03:24:08
【问题描述】:

我有一个模型可以保存一次游览。用户可以更改此短途旅行,但我需要在更改之前知道短途旅行是什么,因为我会跟踪每次短途旅行的“预订”数量,如果您更改短途旅行,我需要从中删除一个预订上一次游览。

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

我猜你为此使用了一个信号?

我应该使用 pre_save、pre_init 还是最好的方法?

pre_save 似乎不是正确的,因为它打印的是新值,而不是我预期的“旧值”

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

【问题讨论】:

  • 如果这是我的应用程序:django model utils field tracker + post_save signal
  • 太酷了!谢谢,让我试试
  • 检查一下。然后让我知道它是否适合您,以便将其发布为答案。祝你好运。
  • django model utils 以什么方式改变你的数据库?
  • 好吧,根据我的阅读,我需要为我的模型使用他们的数据库结构。但这是一个简单的解决方案..在模型保存方法中: print Delegate.objects.get(pk=self.pk).excursion > 这将是旧的,在保存之前

标签: django django-models django-signals


【解决方案1】:

您可以使用 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'))

这将极大地帮助您进行状态更改活动。因为覆盖保存方法不是一个好主意。

【讨论】:

  • 这是最干净的解决方案,无需任何大惊小怪或调整。不错!
  • 如何在模板中访问这个?
【解决方案2】:

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

您的实例的未来版本存储在模型的 Django 形式的 form.instance 中。保存时,会运行验证并将这个新版本应用于模型,然后保存模型。

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

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

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

这是使用 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 将包含已更改的字段,这意味着如果没有更改,则为空。

【讨论】:

    【解决方案3】:

    你有几个选择。

    第一个是覆盖保存方法

    #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  
    

    【讨论】:

    • 第二种方法binding function to post save signal + django model utils field tracker不起作用,因为FieldTracker会查看上次保存后值是否改变。
    • 为我跑。 “保存后”的意思是“保存后”。
    • FieldTracker 给出上次保存后更改的值。它不会为您提供上次保存时更改的值。
    • @eugene,查看 FiekdTraker 文档示例,请参阅previous 示例方法。它在保存之前返回字段值。不是吗?
    • 它在最后一次保存期间返回字段值,而不是在保存之前,这意味着在post_save 上,当您调用previous 时,您会得到self.value
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2020-02-07
    • 2012-05-07
    • 2011-01-13
    相关资源
    最近更新 更多