1

モデルの 1 つが保存されているときにMyModel、フィールドをチェックして、他のモデルで同じ変更をトリガーしたい状況があります。some_key.

コードは正常に動作しますが、シグナルを再帰的に呼び出します。その結果、CPU/DB/API 呼び出しを無駄にしています。私は基本的に信号をバイパスしたいのですが、.save(). 提案はありますか?

class MyModel(models.Model):
    #bah
    some_field = #
    some_key = #

#in package code __init__.py 
@receiver(models_.post_save_for, sender=MyModel)
def my_model_post_processing(sender, **kwargs):
 # do some unrelated logic...
 logic = 'fun!  '


 #if something has changed... update any other field with the same id
 cascade_update = MyModel.exclude(id=sender.id).filter(some_key=sender.some_key)
 for c in cascade_update:
     c.some_field  = sender.some_field 
     c.save()
4

4 に答える 4

7

電話をかける前に信号を切断し、save後で再接続します。

post_save.disconnect(my_receiver_function, sender=MyModel)
instance.save()
post_save.connect(my_receiver_function, sender=MyModel)
于 2011-12-28T22:45:49.250 に答える
3

update() メソッドを使用してシグナルをバイパスすることで解決できます。

cascade_update = MyModel.exclude(
                     id=sender.id).filter(
                     some_key=sender.some_key).update(
                     some_field  = sender.some_field )

「update() メソッドは SQL ステートメントに直接変換されることに注意してください。直接更新の一括操作です。モデルで save() メソッドを実行したり、pre_save または post_save シグナルを発行したりしません」

于 2011-12-28T22:44:43.530 に答える
0

関連オブジェクトの更新コードをMyModel.saveメソッドに移動できます。その場合、信号をいじる必要はありません。

class MyModel(models.Model):
    some_field = #
    some_key = #

    def save(self, *args, **kwargs):
        super(MyModel, self).save(*args, **kwargs)
        for c in MyModel.objects.exclude(id=self.id).filter(some_key=self.some_key):
            c.some_field = self.some_field 
            c.save()
于 2011-12-29T10:23:25.833 に答える