django 保存时检查以前的模型值

xxls0lw8  于 2023-03-09  发布在  Go
关注(0)|答案(4)|浏览(161)

我有一个保存Excursion的模型,用户可以更改这个Excursion,但是我需要在他更改之前知道这个Excursion是什么,因为我跟踪每个Excursion有多少“预订”,如果您更改了您的Excursion,我需要从以前的Excursion中删除一个预订。
我不能完全肯定这件事该怎么办。
我猜你用信号来做这个?
我应该使用pre_保存、pre_init还是使用最适合的方法?
pre_保存看起来不正确,因为它打印的是新值,而不是我预期的“旧值

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

nvbavucw1#

你有几个选择。
第一种是覆盖保存方法

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

第二个是绑定函数到post保存信号+ django模型工具字段跟踪器

@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_保存中:

@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
gwbalxhn

gwbalxhn2#

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

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

8dtrkrch

8dtrkrch3#

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

u1ehiz5o

u1ehiz5o4#

还有一个选择:
Django的文档中有一个例子,展示了如何通过覆盖模型方法来实现这一点。
简而言之:
1.覆盖Model.from_db()以添加包含原始值的动态属性
1.重写Model.save()方法以将新值与原始值进行比较
这具有不需要额外的数据库查询的优点。

相关问题