1

このpost_save/pre_save信号をdjangoから把握するのに苦労しています。

私のモデルにはフィールドがstatusあり、このモデルへのエントリが追加/保存されると、それに応じて何らかの条件でステータスを変更する必要があります。

私のモデルは次のようになります。

 class Ticket(models.Model):    
    (...)   
    status = models.CharField(max_length=1,choices=OFFERT_STATUS, default='O')

そして、pre_save 用に構成された私のシグナルハンドラー:

def ticket_handler(sender, **kwargs):
   ticket = kwargs['instance']
   (...)
   if someOtherCondition:
       ticket.status = 'C'

ticket.save()さて、この最後の行の文のすぐ下に置くとどうなるでしょうかif。これは、このアクションがシグナル自体を呼び出すため、巨大な反復ブラック ホールです。そして、この問題は と の両方pre_saveで発生しpost_saveます。

ええと...保存する前に(または保存した後に)エントリを変更する機能は、djangoの世界ではかなり一般的だと思います。それで、私はここで何が間違っていますか?シグナルは間違ったアプローチですか、それともここで何かが欠けていますか?

また、この pre_save/post_save 関数がトリガーされると、別のモデルのインスタンスにアクセスして、その特定の行エントリを変更することは可能でしょうか?

ありがとう

4

2 に答える 2

8

シグナルは、保存前に同じモデル内のフィールドを更新するための適切なアプローチではありません。この場合、シグナルを使用する代わりに、モデルの save メソッドをオーバーライドします。

def save(self, force_insert=False, force_update=False):
    status = whatever....
    super(Ticket, self).save(force_insert, force_update)

他のモデルを更新する場合、モデルを簡単に分離できるため、シグナルは優れたアプローチです。具体的には、pre_/post_save シグナルを追加してアクションをトリガーすることができます。保存されたモデルのコードを変更する必要はありません (サードパーティの別のアプリケーションに存在する可能性があります)。

于 2010-12-26T20:13:48.773 に答える
3

これはsave(). 信号でこれを行う必要がある場合は、 の周囲が非常にタイトな状態になっていることを確認しくださいsave()。テストは次のように書き直すことができます。

   if someOtherCondition and ticket.status != 'C':
       ticket.status = 'C'
       ticket.save()

この方法でテストを行っても、無限再帰にはなりません。

于 2010-12-27T01:55:34.533 に答える