Reputation: 604
I am reading the documentation for django duration field and I cannot figure out how I can use this to annotate a set of django objects with the duration. The docs say that the db stores durations as integer and to aggregate it needs to be converted to timedelta like so:
timedelta(microseconds=list.aggregate(sum=Sum('duration'))['sum'])
My problem is that I am not sure how to use this expression as an annotation for a set of django objects. The documentation can be found here
Thanks in advance.
Upvotes: 1
Views: 1734
Reputation: 33833
I am not sure how to use this expression as an annotation for a set of django objects
The short answer is: you can't.
If you're talking about annotating a queryset with sums, then I assume the duration
field is on a related model (via many-to-many or reverse foreign key relation) and you want to get the sums of durations for each row of the parent model.
You can annotate the queryset with int duration values in microseconds like so:
qs = MyModel.objects.annotate(sum=Sum('related_model__duration'))
Alternatively you might have the duration
field on MyModel
directly but are aggregating (i.e. an SQL GROUP BY
query):
qs = MyModel.objects.values('grouped_field').annotate(sum=Sum('duration'))
Either way, to convert these to timedeltas you could iterate over the queryset and modify the instances:
for obj in qs:
obj._timedelta = timedelta(microseconds=obj.sum)
Looking at this code it occurs to me I'd prefer to make this a property on the model, eg:
class MyModel(models.Model):
# ...
@property
def timedelta(self):
try:
return timedelta(microseconds=self.sum)
except AttributeError:
# instance was not annotated (from a regular queryset)
return None
Then you don't need to do the extra loop over the queryset.
Upvotes: 1