Ev.
Ev.

Reputation: 1567

How to group querysets by attributes in Django

I have this data structure:

class Currency(Model):
    name = CharField()
    ...

class Invoice(Model):
    currency = ForeignKey(Currency)
    ...

I would like to filter all Invoices grouping them by Currencies. I would like the result to be something like this:

{
    'USD': '<INVOICES_QUERYSET_FOR_USD>',
    'EUR': '<INVOICES_QUERYSET_FOR_EUR>',
    ...
}

Is there an easy way to achieve this or do I have to mount the dictionary myself? I know Annotate gives a similar result, but I just want to group the Queryset by a common attribute value.

Upvotes: 0

Views: 1857

Answers (1)

2ps
2ps

Reputation: 15986

Something like this should get you what you want.

from collections import defaultdict

currencies_of_interest = [ 'USD', 'EUR', ]
qs = Invoice.objects.select_related(
    'currency'
).filter(
    currency__name__in = currencies_of_interest
)order_by('currency__name')
currencies = defaultdict(list)
for x in qs:
    currencies[x.currency.name].append(x)
# now currencies will look like:
# {
#    'USD': list[Invoice] for USD,
#    'EUR': list[Invoice] for EUR,
#     ...
# }

If you prefer working with querysets, and don’t mind doing multiple queries of your database:

currencies_of_interest = [ 'USD', 'EUR', ]
currencies = {}
for x in currencies_of_interest:
    currencies[x] = Invoice.objects.select_related(
        'currency').filter(currency__name=x)
# now currencies will look like:
# {
#    'USD': QuerySet[Invoice] for USD,
#    'EUR': QuerySet[Invoice] for EUR,
#     ...
# }

Upvotes: 2

Related Questions