2016-06-28 25 views
5

Ho un modello chiamato "StoreItem" e un modello denominato "QuoteItem". A QuoteItem punta su un StoreItem.annotato django - conteggio condizionale

Sto tentando di annotare un contatore di quanti punti di quotazione puntano sugli articoli del negozio, ma con condizioni da applicare sugli articoli del preventivo.

Ho provato qualcosa di simile:

items = items.annotate(
      quote_count=Count(
       Case(
        When(quoteitem__lookup_date__in=this_week, then=1), 
        output_field=IntegerField() 
       ) 
      ) 
     ) 

'voci' sono un set di query di StoreItems. 'this_week' è un elenco di date che rappresentano questa settimana (questo è il filtro che cerco di applicare). Dopo aver fatto funzionare le date, voglio aggiungere più filtri a questo conteggio condizionale, ma iniziamo con quello.

Comunque quello che sto ricevendo è più simile a un valore booleano - se Quote elementi che corrispondono esiste la condizione, non importa quante ho, il contatore sarà 1. altro, sarà 0.

Si guarda come lo Count(Case()) controlla solo se esiste qualche elemento e in tal caso restituisce 1, mentre io lo voglio iterare su tutti gli elementi di preventivo che puntano sull'elemento del negozio e li contano, se corrispondono alla condizione (singolarmente).

Come posso farlo?

risposta

7

È necessario avvolgere tutto in un Sum dichiarazione invece di Count (lo trovo un po 'strano che Count opere a tutti):

from django.db.models import Case, IntegerField, Sum, When 

items = items.annotate(
     quote_count=Sum(
      Case(
       When(quoteitem__lookup_date__in=this_week, then=1), 
       output_field=IntegerField() 
      ) 
     ) 
    ) 

questo aggiunge praticamente su tutti i 0 s e 1 s per la interno Case, risultante in un conteggio del numero di corrispondenze.

0

Stavo svolgendo un'attività simile. Per me, Sum su Case/When non funzionava a causa di quante tabelle mi stavo unendo (era molto più che sufficiente). Finito in questo modo:

from django.db.models import Case, IntegerField, Count, When, F 

items = items.annotate(
     quote_count=Count(
      Case(
       When(quoteitem__lookup_date__in=this_week, then=F('quoteitem__id'), 
      ), 
      distinct=True, 
     ) 
    ) 

Nel mio caso ho dovuto aggiungere due Count s insieme come:

items = items.annotate(
     quote_count=Count(
      Case(
       When(quoteitem__lookup_date__in=this_week, then=F('quoteitem__id'), 
      ), 
      distinct=True, 
     ) 
    ) + Count (
      Case(
       When(itemgroup__lookup_date__in=this_week, then=F('itemgroup__quoteitem__id'), 
      ), 
      distinct=True, 
     ) 

Supponendo che items può essere correlata ad quoteitems sia attraverso un itemgroup o direttamente.

Problemi correlati