2009-02-13 9 views
5

Sto tentando di scrivere una vista che genererà un rapporto che visualizza tutti gli elementi nel mio sistema di inventario e fornisce riepiloghi a un certo punto. A proposito, questo rapporto è puramente solo un modello HTML.Generazione di elenchi/rapporti con riepiloghi in linea in Django

Nel mio caso, ogni articolo è parte di un ordine. Un ordine può avere diversi articoli e voglio poter visualizzare riepiloghi basati su SUM dopo la fine di ogni ordine.

Così il rapporto tipo di assomiglia a questo:

Order #25  <Qty> <Qty Sold> <Cost> <Cost Value> 
Some Item   2  1  29.99 29.99 
Another Item  4  0  10.00 40.00 
<Subtotal Line> 6  1  39.99 69.99 
Order #26  <Qty> <Qty Sold> <Cost> <Cost Value> 
... Etc, you get the point 

Ora, io sono perfettamente in grado di visualizzare tutti i valori e hanno già un rapporto che mostra tutte le voci, ma non ho idea di come posso posizionare i subtotali all'interno del report come quello senza fare molto di query. I campi Quantità, Qtà venduti e Costo sono solo una parte del modello Articolo e il valore di costo è solo una semplice funzione del modello.

Qualsiasi aiuto sarebbe apprezzato. Grazie in anticipo :-)

risposta

3

I totali sono SELECT SUM(qty) GROUP BY order_number cose.

Sono completamente separati da una query per ottenere dettagli.

I risultati delle due query devono essere intercalati. Un buon modo per farlo è creare ogni ordine come una tupla (list_of_details, appropriate summary).

Poi il display è facile

{% for order in orderList %} 
    {% for line in order.0 %} 
     {{ line }} 
    {% endfor %} 
    {{ order.1 }} 
{% endfor %} 

La parte difficile è interleaving le due query.

details = Line.objects.all() 
ddict = defaultdict(list) 
for d in details: 
    ddict[d.order_number].append(d) 

interleaved= [] 
subtotals = ... Django query to get subtotals ... 
for s in subtotals: 
    interleaved.append((ddict[s.order], s.totals)) 

Questo interleaved oggetto può essere dato al modello per il rendering.

+0

Grazie mille! Dopo aver giocato un po 'con il Django ORM per ottenere la corretta funzionalità GROUP BY, ho praticamente funzionato. Grazie ancora – Bartek

1

È possibile calcolare i subtotali in Python nella vista Django.

I totali parziali possono essere memorizzati in istanze dell'oggetto Modello con un attributo che indica che si tratta di un totale parziale. Per mantenere semplice il modello del report, è possibile inserire gli oggetti del totale parziale nelle posizioni giuste nell'elenco dei risultati e utilizzare l'attributo del sub-totale per rendere le linee del totale parziale in modo diverso.

+0

Quindi stai dicendo di passare in loop attraverso il queryset 'report' creato tramite Python, e quando riconosce che sono in un nuovo ordine, riassumo quel gruppo di valori di elementi, quindi inietto l'attributo sub-total all'interno del elencare al punto giusto? Spero che abbia senso, è la mia migliore idea al momento. – Bartek

+0

Concettualmente, sì. L'implementazione effettiva potrebbe evitare di dover rilevare un nuovo ordine utilizzando un dizionario di subtotale o qualche altra implementazione. –

1

Supponendo che non hai intenzione di utilizzare tutti i campi specifici di ordine, è possibile eseguire query di DB singolo seguito da alcuni calcoli pitone:

from itertools import groupby 
items = OrderItem.objects.select_related('order').order_by('order').all() # order_by is essential 
items_by_order = dict(groupby(items, lambda x: x.order)) 
for order, items in items_by_order: 
    items_by_order[order]['subtotals'] = ... # calculate subtotals for all needed fields 

Questo è l'approccio più generico rispetto al utilizzando query SQL separeate per il calcolo i subtotali che impongono la responsabilità di sincronizzare le clausole WHERE su entrambe le query. Puoi anche utilizzare qualsiasi funzione di aggregazione, non solo quella disponibile sul lato DB.

Problemi correlati