Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django annotation on field added with extra

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.

like image 862
John Avatar asked May 17 '11 09:05

John


People also ask

What is the difference between aggregate and annotate in Django?

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() .

What is Queryset 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.

How does annotate work in Django?

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.

Why annotate is used in Django?

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.


2 Answers

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')
like image 136
Ghariani Mohamed Avatar answered Oct 14 '22 07:10

Ghariani Mohamed


Try something like this:

total_done = qs.extra(select = {'total_amount': 'SUM(one_column + another_column)'}, )
like image 43
yedpodtrzitko Avatar answered Oct 14 '22 08:10

yedpodtrzitko