[Django]-Aggregating a QuerySet to get Sum of FileFields size

3👍

It’s impossible to do this with the ORM since it can only generate aggregations against database fields, while file.size is a dynamic attribute provided by the storage backend.

That said, you’re probably better of saving this information in your actual database at upload time, so you can avoid the overhead of iterating over all files.

class Doc(models.Model):
    created_on = models.DateTimeField(auto_now_add=True)
    file = models.FileField(storage=gridfs_storage, upload_to='/')
    file_size = models.PositiveIntegerField()

    def save(self, *args, **kwargs):
        self.file_size = self.file.size
        super(Doc, self).save(*args, **kwargs)

Now aggregations work as expected since you’re dealing with a database field:

Doc.objects.all().aggregate(Sum('file_size'))

2👍

A hcalves pointed out this is not possible using the straight ORM. I’m assuming your db is already done and set so why can’t you just do this?

total_size = sum([ x.file.size for x in Doc.objects.all() ])

Just a thought?

Leave a comment