2

我使用 django-nonrel,Postgre 作为数据库,Mongo 作为文件存储。

我的模型看起来像这样并且工作正常

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

并且工作正常

Doc.objects.all()[0].file.size
108776

现在我正在尝试聚合大小以获得查询集的总大小。

我试过了

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

但是这个扔

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/zoidberg/dev/backus/lib/python2.6/site-packages/django/db/models/query.py", line 321, in aggregate
    is_summary=True)
  File "/Users/zoidberg/dev/backus/lib/python2.6/site-packages/django/db/models/sql/query.py", line 974, in add_aggregate
    field_list, opts, self.get_initial_alias(), False)
  File "/Users/zoidberg/dev/backus/lib/python2.6/site-packages/django/db/models/sql/query.py", line 1417, in setup_joins
    raise FieldError("Join on field %r not permitted. Did you misspell %r for the lookup type?" % (name, names[pos + 1]))
FieldError: Join on field 'file' not permitted. Did you misspell 'size' for the lookup type?
    enter code here

知道是否可以使用 ORM 或者我必须自己迭代文件?

4

2 回答 2

2

使用 ORM 是不可能做到这一点的,因为它只能针对数据库字段生成聚合,而file.size它是存储后端提供的动态属性。

也就是说,您最好在上传时将此信息保存在您的实际数据库中,这样您就可以避免遍历所有文件的开销。

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)

现在聚合按预期工作,因为您正在处理数据库字段:

Doc.objects.all().aggregate(Sum('file_size'))
于 2012-06-18T20:30:07.450 回答
2

一个 hcalves 指出使用直接 ORM 是不可能的。我假设您的数据库已经完成并设置,那么您为什么不能这样做呢?

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

只是一个想法?

于 2012-06-18T20:40:36.300 回答