2016-10-14 7 views
1

私がモデルを持っているが変更されたときにメソッド保存モデルをカスタマイズする方法、のは保存でき、定義は以下の通りである:このモデルでは、A、BのDjangoは - 指定したフィールドが

class A(models.Model): 
    name = models.CharField('name', max_length=10) 
    enabled = models.BooleanField('enabled', default=False) 
    field1 = models.CharField('field1', max_length=10) 
    field2 = models.CharField('field2', max_length=10) 
    field3 = models.CharField('field3', max_length=10) 
    parent = models.ForeignKey('self', null=True, blank=True) # hierarchy 

と、いくつかのオブジェクトインスタンス、c、d。階層は親フィールドで表されます。

a 
|-- b 
    |-- c 
    |-- d 

だから、私は何をする必要があることは、ときb.enabledTrueからFalseからの変更、またはその逆に、私は値にc.enabledd.enabledを更新する必要がありますされていますb.enabled

つまり、親のenabledフィールドが変更されたときに子インスタンスに変更をブロードキャストする必要があります。

パフォーマンスを考慮すると、enabledフィールドが実際に変更されたときにのみ変更をブロードキャストする必要があります。また、親が保存されているときは常に、子インスタンスを更新する必要はありません。フィールド1またはフィールド2のみを更新します。

だから誰も知っている、このロジックを実装する最良の方法は何ですか?前もって感謝します。

答えて

1

これを行うための最善の方法使用しているDjangoの信号https://docs.djangoproject.com/es/1.10/ref/signals/

モデルが呼び出すときには、この方法save()

from django.db.models.signals import pre_save 

def change_status(sender, instance, **kwargs): 
    # instance object is the model that you have called the method save 
    a = A.objects.get(id=instance.id) # or B or C model 
    if instance.enable: 
     a.enable = False 
     # my code..... 

pre_save.connect(change_status, sender=A) 
# sender is the model that will be called every time you call the method save 

メソッドchange_statusを呼び出します、それはそれはオブジェクトことを覚えておいてください ですインスタンスは変更する前のモデルなので、a.enable=Trueがある場合は を、change_statusシグナルではsave()というメソッドを呼び出してquこの変更がなければ、エイリアイはa.enable=True intance.enable >> Truea.enable >> Falseはまだ保存されていないためです。

+0

これは、変更をキャプチャする別の方法ですが、オブジェクトが保存されているときはいつでもオブジェクトを照会する必要があります。 – Enix

+0

いいえ、djangoシグナルでは、(この場合は)chage_statusメソッドを1つの関数(このシグナル内)でのみ実装します.A.save()を実行するたびに関数が呼び出され、同じどのような状況でも状況を変更するプロセスがあり、それがプロセスです。それは理解できません。誰が理解できないのですか? –

1

簡潔に - いいえ。しかし、手動でsaveメソッドをオーバーロードすることもできます。

class B(models.Model): 

    ... 

    def save(self, *args, **kwargs): 
     if self.pk is not None: 
      original = B.objects.get(pk=self.pk) 
      if original.enabled != self.enabled: 
       C.enabled = self.enabled 
       C.save() 
       D.enabled = self.enabled 
       D.save() 
     super(B, self).save(*args, **kw) 
+0

hmm。これを行う方法だとわかっていますが、モデルを保存するたびにクエリを実行する必要があります。私はこのトピックがこのトピックに関連していることを発見しました。 http://stackoverflow.com/questions/23361057/django-comparing-old-and-new-field-value-before-saving私はModelFormレベルでこのロジックを実装する方がModelレベルでこれを行うよりも優れていると思います。とにかく、お返事ありがとうございました。 – Enix

+0

これをトランザクションで実行すると、すべてのクエリが1回のトランザクションで実行されます。それには何も問題ありません。 –

関連する問題