I'm trying to find a way to take an annotation over two fields on a model added together. Something like:
total_done = qs.values(
'ability__ability_name',
).extra(
select={
'total_amount': 'effective_value + overage',
}
).annotate(
total=Sum('total_amount'),
).values(
'ability__ability_name', 'total_amount'
).order_by('-total_amount')
The above doesn't work and yields the error "Cannot resolve keyword 'total_amount' into field" I already tried the solution indicated here: Using .aggregate() on a value introduced using .extra(select={...}) in a Django Query? However no luck still get the "Cannot resolve keyword 'total_amount' into field"
Anything other than performing the query in raw sql as the querystring that's being passed in could have various filters and excludes already performed on it making that prospect a little complicated. I'm also trying to avoid adding the field to the actual model and calculating it's value during save unless that's the only way.
Unlike aggregate() , annotate() is not a terminal clause. The output of the annotate() clause is a QuerySet ; this QuerySet can be modified using any other QuerySet operation, including filter() , order_by() , or even additional calls to annotate() .
In simpler terms, annotate allows us to add a pseudo field to our queryset. This field can then further be used for filter lookups or ordering.\ Ex: Suppose you want to all the Books along with the total number of chapters present in each one, then you could use annotate as follows: Simple annotate example.
In the Django framework, both annotate and aggregate are responsible for identifying a given value set summary. Among these, annotate identifies the summary from each of the items in the queryset. Whereas in the case of aggregate, the summary is calculated for the entire queryset.
The Django ORM is a convenient way to extract data from the database, and the annotate() clause that you can use with QuerySets is also a useful way to dynamically generate additional data for each object when the data is being extracted.
I think its better to user annotation to get the total_amount value:
total_done = qs.values(
'ability__ability_name',
).annotate(
total_amount=F('effective_value') + F('overage')
total=Sum('total_amount'),
).values(
'ability__ability_name', 'total_amount'
).order_by('-total_amount')
Try something like this:
total_done = qs.extra(select = {'total_amount': 'SUM(one_column + another_column)'}, )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With