2012-08-03 8 views
6

モデルで対称関係を作成し、関係にフィールドを追加したいとします。私は​​(そしてまたthis another blog)を見つけて、自分のモデルを作成するステップに従った。DjangoのManyToManyFieldに対称オブジェクトを自動的に作成するには?

class CreditCardIssuer(models.Model): 
    name = models.CharField(_('name'), max_length=256) 
    transfer_limits = models.ManyToManyField('self', through='Balancetransfer', related_name='no_transfer_allowed+', symmetrical=False, help_text=_('List of issuers to which balance transfer is not allowed.')) 

    def add_balancetransfer(self, creditcardissuer, until): 
     balance_transfer, _newly_created = Balancetransfer.objects.get_or_create(
      no_transfer_from=self, 
      no_transfer_to=creditcardissuer, 
      until=until) 
     balance_transfer, _newly_created = Balancetransfer.objects.get_or_create(
      no_transfer_from=creditcardissuer, 
      no_transfer_to=self, 
      until=until) 
     return balance_transfer 

    def remove_balancetransfer(self, creditcardissuer, until): 
     Balancetransfer.objects.filter(
      no_transfer_from=self, 
      no_transfer_to=creditcardissuer, 
      until=until).delete() 
     Balancetransfer.objects.filter(
      no_transfer_from=self, 
      no_transfer_to=creditcardissuer, 
      until=until).delete() 
     return 

    def get_transfer_limits(self, until): 
     return self.transfer_limits.filter(
      no_transfer_to__until=until, 
      no_transfer_to__no_transfer_from=self) 


class Balancetransfer(models.Model): 
    no_transfer_from = models.ForeignKey('CreditCardIssuer', related_name='no_transfer_from') 
    no_transfer_to = models.ForeignKey('CreditCardIssuer', related_name='no_transfer_to') 
    until = models.IntegerField(blank=True, null=True, help_text='Minimum card ownership period to allow balance transfer.') 

    class Meta: 
     unique_together = ('no_transfer_from', 'no_transfer_to') 

ただし、管理者から関係を作成すると、1つだけが作成されます。あなたは問題を理解するのを助けてくれますか?

+0

あなたは多分あなたは_only 1で何を意味するかを詳細にもう少し手の込んだcreated_のですか?あるいは、何が起こると思いますか? –

+0

機能CreditCardIssuer.add_balancetransferは、管理者から関係を作成するときに達成したいことを示します。そうすれば、両方のオブジェクトの関係が作成されます。それを解決する時間を取ってくれてありがとう。 – noel

+0

2つの関係は「自動的に」作成されません。あなたが期待している動作については100%明確ではありません。あなたは精緻化できますか? – coleifer

答えて

1

あなたはDjangoの管理者の半分を持っていると言います(あなたは言いませんが、あなたがコードを投稿しない限り動作します)。残りのステップは、関係が欠けている。

私はあなたがあなたの add_balancetransfer()法( import pdb; pdb.set_trace())にブレークポイントを置けば、あなたはそれが呼び出されないされないされていることを見つけることが疑われる

からが作成されること関係の一部は、組み込みのDjangoの管理者の行動を介して行われます。

要するに、モデルを保存するときにadd_balancetransfer()に電話するか、欠けている関係のみを追加する別のバージョンにする必要があります。

これを行う方法の1つはoverriding the model's save() methodですが、これは少し壊れやすい可能性があります。あなたの状況のた​​めに、model's post_save signalで不足している関係で埋めるために良い仕事があります

from django.db.models.signals import post_save 
from django.dispatch import receiver 

from yourapp.models import CreditCardIssuer 

@receiver(post_save, sender=CreditCardIssuer) 
def add_missing_relationship(sender, **kwargs): 
    # Add the other side of what should be a symmetrical relationship 
    ... 
+0

提案していただきありがとうございます。私はすでにこれらのメソッド内でいくつかのログを追加し、決して呼び出されないことを確認しました。リバースリレーションシップオブジェクトを自動的に作成する方法がない場合、おそらくsave()メソッドをオーバーライドして行きます。 – noel

+0

@supervacuoはタイプミスのようです。あなたのインポートはpost_save用で、受信者はpre_saveを使用します。 – hobs

+0

@hobs良いキャッチ、ありがとう。今すぐ 'post_save'に修正されました。 – supervacuo

関連する問題