2016-12-11 2 views
0

モデルの識別子を作成する簡単な信号を作成しようとしています。Django post_save信号はpre_saveのように動作します

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オブジェクトが保存される毎回、私はだから私はpost_save信号を作成し[weekhour_obj.hour for weekhour_obj in scheduler.weekhours.all()]

のリストに参加identificatorを作成または更新します。問題は、Schedulerを保存すると、信号がpre_saveのように機能することです。スケジューラー用に設定されたworkhoursは古いものであり、更新されていません。私が2回目にそれを保存するとき、それは動作します。

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

どこに問題があるのでしょうか?

EDIT - 例:私は信号方式では最初の行にprint instance.weekhours.all()を置くとき

それはこのように動作します

時間2時間4とweekhoursとDjangoのadminにスケジューラオブジェクトを作成し
  1. 。 それは何も印刷しませんでした。
  2. adminにスケジューラを開いて、それが<QuerySet [<WeekHour: 5>]>

印刷しかし、それはpost_saveで再びスケジューラを開いて、6,7 にweekhoursを変更<QuerySet [<WeekHour: 2>,<WeekHour: 4>]>

  • 印刷5 に2及び4からWeekHoursを変更それでなぜそれがpre_saveだったかのように振る舞うのですか?

  • 答えて

    1

    Many-to-manyリレーションシップは親オブジェクトを先に保存する必要があります。保存するまで、アイテムはSchedulerインスタンスに関連付けることはできません。

    あなたの例では、post_saveinstance.weekhours.all()を取得しようとしているが、それは最初saveに常にNone戻ります。そのためには値を取得するために別の保存を行う必要があります。

    あなたはidentificator

    を作成する代わりに post_savem2m_changedを使用することができます
    関連する問題