Django-将值从pre_save传递到模型上的post_save方法

时间:2018-08-04 21:39:32

标签: python django

我有一个像这样的Django模型...

class Example(models.Model):
    title = models.CharField(...)
    ...

我正在尝试比较两个值-用户更改之前的title字段和之后的title字段。我不想一次将两个值都保存在数据库中(只需要一个title字段),所以我想使用pre_savepost_save方法来做到这一点。是否可以在保存之前获取标题,然后保留该值以传递到post_save方法中?

pre_save和post_save方法看起来像这样...

@receiver(pre_save, sender=Example, uid='...')
def compare_title_changes(sender, instance, **kwargs):
    # get the current title name here
    x = instance.title

@receiver(post_save, sender=Example, uid='...')
def compare_title_changes(sender, instance, **kwargs):
    # get the new title name here and compare the difference
    x = instance.title # <- new title
    if x == old_title_name: # <- this is currently undefined, but should be retrieved from the pre_save method somehow
        ...do some logic here...

任何想法将不胜感激!

修改

正如我所指出的,pre_save和post_save都在调用save()之后发生。我一直在寻找类似于pre_save()的东西,但是在调用实际的save方法之前。我在模型上进行了设置,以便无论实例保存在何处(管理员或用户视图),都可以访问要执行的逻辑

2 个答案:

答案 0 :(得分:2)

使用Example.objects.get(pk=instance.id)pre_save处理函数中从数据库中获取旧标题:

@receiver(pre_save, sender=Example, uid='...')
def compare_title_changes(sender, instance, **kwargs):

    new_title = instance.title  # this is the updated value
    old_title = Example.objects.get(pk=instance.id)
    # Compare the old and new titles here ...

这个技巧是很久以前here提出的。我尚未使用最新的Django版本进行测试。请让我知道它是否仍在工作。

答案 1 :(得分:0)

我们只能说,如果“保存”方法成功通过,则对象已更改,因此最好使用post_save以确保模型对象已更新。

在模型类实例上设置fly属性可以完成此任务,因为同一实例是从pre_save传递到post_save的。

def set_flag_on_pre_save(sender, instance, *args, **kwargs):
    # Check here if flag setting condition satisfies
    set_the_flag = true
    if set_the_flag:  
      instance.my_flag=0


def check_flag_on_post_save(sender, instance, *args, **kwargs):
   try:
      print(instance.my_flag)
      print('Flag set') 
   except AttributeError:
      print('Flag not set')


pre_save.connect(set_flag_on_pre_save, sender=ModelClass)

post_save.connect(check_flag_on_post_save, sender=ModelClass)