I have a result from the DB which I want to enriche with a row. A queryset is a dict right? So I created a new dict and wanted to merge those two. But it told me you cant merge a dict and QuerySet. How can this be done?
The Query
years = (Transactions.objects
.annotate(year=TruncYear('timestamp'))
.values('year')
.order_by('-year')
.annotate(total=Sum('amount'))
.annotate(earnings=Sum('amount', filter=Q(amount__gt=0)))
.annotate(spent=Sum('amount', filter=Q(amount__lt=0)))
.annotate(count=Count('id'))
.values('year', 'total', 'count', 'earnings', 'spent'))
I check if the result contains the current year, if not i than want to add it with 0
A QuerySet
is not a dictionary. Essentially a QuerySet
is Django's representation of a query to the database that will return a (possibly empty) set of values. The query does not per se has to be fired to the database: QuerySet
s are lazy, so only if you somehow need the result, for example because you are going to enumerate over the result, it will fire the query.
This is probably also the main reason why injecting extra data in a QuerySet
is simply not a good idea: a QuerySet
does not only allow to enumerate over, but you can perform a set of operations on it that then create new QuerySet
. So if you would insert an extra item in the QuerySet
, and you decide to call .filter(…)
on that QuerySet
, then how should that be handled then?
I would suggest that you convert the items to the collection like a list and insert the item in that collection. For example:
years = list(
Transactions.objects.values(year=TruncYear('timestamp'))
.annotate(
total=Sum('amount'),
earnings=Sum('amount', filter=Q(amount__gt=0)),
spent=Sum('amount', filter=Q(amount__lt=0)),
count=Count('id'),
)
.order_by('-year')
)
if not years or years[0]['year'] != 2025:
years.insert(
0, {'year': 2025, 'total': 0, 'count': 0, 'earnings': 0, 'spent': 0}
)