2009-06-05 12 views
2

私はこの質問が複数回掲載されていることを知っていますが、私はまだこの問題に対する明確な答えを見つけることができませんでした。だから、私は行く:DjangoモデルカスタムSave ManyToManyField問題

class Invoice(models.Model): 
    program = models.ForeignKey(Program) 
    customer = models.ForeignKey(Customer, related_name='invoices') 
    participants = models.ManyToManyField(Participant, related_name='participants_set') 
    subtotal = models.DecimalField(max_digits=10, decimal_places=2, default='0.00', blank=True, null=False) 
    pst = models.DecimalField("PST", max_digits=10, decimal_places=2, default='0.00', blank=True, null=False) 
    gst = models.DecimalField("GST", max_digits=10, decimal_places=2, default='0.00', blank=True, null=False) 
    total = models.DecimalField(max_digits=10, decimal_places=2, default='0.00', blank=True, null=False) 

    def save(self, **kwargs): 
     super(Invoice, self).save(**kwargs) 
     items = self.participants.count() 
     subtotal = Decimal(self.program.fee) * items 
     pst = self.program.is_pst and Decimal(PST)*subtotal or Decimal('0.00') 
     gst = self.program.is_gst and Decimal(GST)*subtotal or Decimal('0.00') 
     total = (subtotal + pst) + gst 
     self.subtotal = subtotal 
     self.pst = pst 
     self.gst = gst 
     self.total = total 
     super(Invoice, self).save(**kwargs) 

すべてがうまくいきますが、self.participants.count()は動作しません。どんなアイデアであっても問題ではありません。どんな助けでも大歓迎です。

+1

どのバージョン:ソリューションはadmin.ModelAdminからのManyToManyFieldを削除するだけでしたか? self.participants.count()の呼び出しがうまくいくはずです。 – Harold

+0

countメソッドは例外を発生させますか、それとも間違った値を返しますか? –

答えて

0

saveメソッドをオーバーライドする代わりに、pre-save signalを使用することをおすすめします。コードを少しきれいにするだけでなく、次のような奇妙な問題を回避するのに役立ちます:)

0

私は、保存中に参加者の数を試しているため、すべてが見つからない可能性があると思います。データベースの作成時にこの数に依存している場合は、InvoiceにまだIDが割り当てられていないため、多対多のテーブルが正しく同期されるとは思われません。

逆に、他の参加者はデータベースに保存されないことがあります。どちらの方法でも、保存中はこの番号に応じて、信号を使用するかどうかに関係なく機能しません。この計算を行う別の方法をお勧めします。よりクリーンで保存のパフォーマンスが向上し、保存せずに呼び出すことができます。

+0

参加者を完全に分離して数量(参加者数)を記録することをお勧めします。そうすれば、請求書モデルはより一般的になります。 –

0

私にも同様の問題がありました。私はdel.icio.usスタイルタグをサポートするモデルを持っていました。 save関数は、ヘルパー関数update_tags()(以下の簡単な例を参照してください)を呼び出すことによって、タグのリスト(例えば、 "python django web")を解析し、個々のタグオブジェクトインスタンスに変換します。ただし、ManyToManyFieldは管理インターフェイス内でオブジェクトを編集したときに変更を反映しません。

class Article(models.Model): 
    tag_string = models.CharField(max_length=255, null=True, blank=True) #del.icio.us style tags, like: django python software 
    tags = models.ManyToManyField(Tag, blank=True) 

    def save(self, force_insert=False, force_update=False): 
     super(Article, self).save(force_insert, force_update) 

     self.update_tags() #The result of this function didn't seem to be saved in the ManyToManyField 

管理インターフェイスがManyToManyFieldの変更をオーバーライドしていたことが判明しました。ジャンゴの

class ArticleAdmin(admin.ModelAdmin): 
    exclude = ['tags'] 
関連する問題