stillinbeta
stillinbeta

Reputation: 1997

Mathematical Operations on Django Annotations

I have a Django model that defines a TimeSlot. Each TimeSlot can hold a certain number of users (TimeSlot.spots). Each TimeSlot also has a certain number of users already held in it (a many to many field, TimeSlot.participants.

When I pass to the template that displays the available TimeSlots to the user, I annotate with TimeSlot.objects.annotate(Count('participants')),which gives the number of users currently held by the TimeSlot as participants__count.

However, what I really want is the number of spots remaining, the capacity (TimeSlot.spots) minus the number currently held (participants__count). How can I annotate another field with this new number, so I can pass it to the template?

Upvotes: 3

Views: 2272

Answers (2)

Ivan Anishchuk
Ivan Anishchuk

Reputation: 485

It's still not possible with annotation (though it is planned to implement in Django). But you can do it with an .extra() query. See my answer to another question for details.

Upd.:

Essentially, you need somethig like this query:

items = MyModel.objects.extra(
    select = {'variance': 'Model.someField - SUM(relatedModel__someField)'},
)

Upvotes: 3

priestc
priestc

Reputation: 35170

Not possible with only an annotation. I'd create a method on the model which does the annotation, and then subtract that from your TimeSlot.spots value. This will use more database queries, but thats your only option. Or I guess you could drop down to raw SQL...

Upvotes: 1

Related Questions