【问题标题】:Django post_save signal acts like pre_saveDjango post_save 信号的作用类似于 pre_save
【发布时间】:2017-04-26 18:12:34
【问题描述】:

我正在尝试创建一个为模型创建标识符的简单信号。

class Scheduler(models.Model):
    weekhours = models.ManyToManyField('WeekHour', related_name='schedulers')
    identificator = models.TextField(null=True,blank=True)

class WeekHour(models.Model):
    hour = models.PositiveSmallIntegerField(verbose_name='Hour in week (0 - 7*24')

每次保存Scheduler对象时,我想创建或更新identificator加入[weekhour_obj.hour for weekhour_obj in scheduler.weekhours.all()]列表

所以我创建了一个post_save 信号。问题是当我保存Scheduler 时,信号的行为就像是pre_save。为调度程序设置的workhours 是旧的,未更新。当我第二次保存它时它可以工作。

@receiver(post_save,sender=models.Scheduler)
def set_identificator(sender,created,instance,**kwargs):
    identificator = ','.join([str(x.hour) for x in instance.weekhours.all().order_by('hour')])
    models.Scheduler.objects.filter(pk=instance.pk).update(identificator = identificator)

你知道问题出在哪里吗?

编辑 - 示例:

当我将print instance.weekhours.all() 放在信号方法的第一行时,它的行为是这样的:

  1. 在 Django admin 中创建了一个调度程序对象,其中包含 weekhours 和第 2 小时和第 4 小时。 它什么也没打印。
  2. 在管理员中打开调度程序并将 WeekHours 从 2 和 4 更改为 5。 它打印了<QuerySet [<WeekHour: 2>,<WeekHour: 4>]>
  3. 再次打开调度程序并将工作日更改为 6 和 7。 它打印了<QuerySet [<WeekHour: 5>]>

但它是一个post_save 信号,为什么它的行为就像pre_save

【问题讨论】:

    标签: python django django-models django-signals


    【解决方案1】:

    Many-to-many 关系需要先保存父对象,在保存之前,您不能将项目与 Scheduler 实例关联。

    在您的示例中,您试图在post_save 中获取instance.weekhours.all(),但它会在第一个save 中始终返回None。为此,您需要再次保存以获取值。

    您可以使用m2m_changed 代替post_save 来创建标识符

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-09
      • 2014-03-16
      • 2010-11-16
      • 2021-04-09
      • 2011-09-03
      • 2020-04-08
      • 2011-12-22
      • 2013-07-14
      相关资源
      最近更新 更多