2009-06-10 7 views
1

Je dois effectuer une série de calculs simples sur un objet modèle Facture, auquel sont associés un certain nombre d'enfants de commande contenant la quantité de commande et la valeur de la commande, etc. Tout est géré via le formulaire d'administration de la facture (avec commande comme inline)Quelle est la manière la plus simple d'effectuer des calculs totaux sur des objets enfants?

Le code que je travaille avec exécute maintenant ces calcs comme ceci:

facture (models.py)

def save(): 
    #get the total of all associated orders 
    for order in self.invoice_orders.all(): 
    self.invoice_net_total += order.order_value 
    super(Invoice, self).save() 

ce qui provoque quelques problèmes lors de la modification d'une quantité d'ordre et de l'enfant puis enregistrez le formulaire - j'obtiens le total précédent au lieu du w total, seulement quand je sauvegarde à nouveau le total se corrige lui-même. Peut-être en raison de la façon dont Django enregistre les objets parents et enfants?

Autre option que je caressais se déplaçait ce calcul à l'objet de commande de l'enfant (préparer un code affreux):

commande (models.py)

def save(): 
    if not self.id: 
    self.invoice.invoice_net_total += self.order_value 
    elif self.id: 
    #grab old instance 
    old = Order.objects.get(pk=self.id) 
    #remove that old total 
    self.invoice.invoice_net_total -= old.order_value 
    self.invoice.save() 
    #add new total 
    self.invoice.invoice_net_value += self.order_value 
    self.invoice.save() 

Bien que ce n'est pas soit très efficace. Je me demandais si quelqu'un pouvait me guider vers un moyen simple de s'assurer que ces calculs fonctionnent comme ils le devraient? Pensée de signaux (relativement nouveau pour moi) mais je me demandais si c'était exagéré. Je pense probablement à ça!

Merci

Répondre

4

D'un autre avis, n'envisagez même pas d'enregistrer explicitement le total de la facture. Au lieu de cela, il peut être recalculé dynamiquement chaque fois que vous demandez une facture. Je pense que c'est une meilleure modélisation car elle évite les données redondantes et éventuellement incohérentes. SQL et Django sont assez intelligents pour calculer le total de vos factures sans trop de frais chaque fois que vous en avez besoin. Esp. vous ne faites pas la sommation dans votre programme si vous utilisez un aggregation function

+0

L'agrégation est probablement la meilleure option, mais sachez que l'agrégation n'est pas disponible dans Django 1.0, mais 1.1 (avec agrégation) devrait être sorti "n'importe quel jour maintenant (tm) "- et le tronc SVN est assez stable pour l'utiliser dès maintenant :) – mikl

+1

Merci agrégation serait fantastique hélas je suis coincé avec Django 1.0.2 pour le moment, mais vous m'avez donné une idée - j'ai résolu cela avec une déclaration de propriété méthode dans le modèle, j'ai réalisé que je n'ai pas besoin de commettre explicitement le total à un champ - fonctionne parfaitement. À votre santé. – user108791

0

Me pense que vous devez enregistrer explicitement les objets enfants avant de faire le calcul, puisque votre requête fait référence à des objets comme dans la base de données, alors que tout objet modifié de la forme peut ne pas avoir été vous sauvé.

Questions connexes