2009-06-05 8 views
2

Ich weiß, dass diese Frage mehrmals gepostet wurde, aber ich konnte noch keine endgültige Antwort auf dieses Problem finden. Also, hier gehe ich:Django Modell benutzerdefinierte speichern mit ManyToManyField Problem

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) 

Alles funktioniert gut, außer self.participants.count() funktioniert nicht. Irgendeine Idee, was das Problem sein könnte. Jede Hilfe wird sehr geschätzt.

+1

Welche Version von Django? Ihr Aufruf an self.participants.count() sollte funktionieren. – Harold

+0

Führt die Count-Methode eine Ausnahme oder gibt es den falschen Wert? –

Antwort

0

Anstatt die Speichermethode zu überschreiben, empfehle ich die Verwendung der pre-save signal. Abgesehen davon, dass Sie Ihren Code ein wenig sauberer machen, hilft es, seltsame Probleme wie diese zu vermeiden :)

0

Ich denke, was passiert, weil Sie versuchen, eine Teilnehmerzahl während eines Speicherns zu zählen, wird die Abfrage möglicherweise nicht alles finden. Wenn Sie bei der Erstellung der Datenbank von dieser Nummer abhängig sind, kann die number-to-many-Tabelle nicht korrekt synchronisiert werden, da der Invoice noch keine ID zugewiesen ist.

Umgekehrt können die anderen Teilnehmer nicht in der Datenbank gespeichert werden. Wie auch immer, abhängig von dieser Nummer wird während eines Speicherns nicht funktionieren, unabhängig von der Verwendung von Signalen. Ich würde empfehlen, eine separate Methode zu haben, die diese Berechnung durchführt. Es ist sauberer, es verbessert die Leistung und Sie können es ohne zu speichern aufrufen.

+0

Hört sich gut an, die Teilnehmer ganz zu trennen und nur die Anzahl (Teilnehmerzahl) zu erfassen. Auf diese Weise wäre das Rechnungsmodell generischer. –

0

Ich hatte ein ähnliches Problem. Ich hatte ein Modell, das del.icio.us Style Tags unterstützt. Die Speicherfunktion würde eine Liste der Tags analysieren (z. B. "python django web") und sie in einzelne Tag-Objektinstanzen durch Aufrufen einer Hilfsfunktion update_tags() (siehe unten für ein vereinfachtes Beispiel) konvertieren. Das ManyToManyField würde jedoch die Änderungen nicht wiedergeben, wenn ich das Objekt in der Verwaltungsoberfläche bearbeitet habe.

Es stellt sich heraus, dass die Verwaltungsschnittstelle die Änderungen an dem ManyToManyField überschreibt. Die Lösung war einfach die ManyToManyField vom admin.ModelAdmin zu entfernen:

class ArticleAdmin(admin.ModelAdmin): 
    exclude = ['tags']