【问题标题】:Django Image Upload...Prevent huge file uploadsDjango Image Upload...防止大文件上传
【发布时间】:2011-08-11 16:33:12
【问题描述】:

我的网站依赖于用户上传的图像文件。我想限制 max_upload_size。

我知道你可以在 settings.py 中设置 FILE_UPLOAD_MAX_MEMORY_SIZE。如果上传的文件大于此大小,则会将其写入 tmp 目录中的磁盘。这几乎可以处理事情吗?巨大的图片仍然会影响我网站的性能吗?

我见过的另一种方法是在 apache 中配置 max_upload_size,它(似乎)包含在 php.ini 中。听起来对吗?可取吗?

另一个步骤涉及检查文件对象的属性。我浏览了这个提供表单验证方法的片段(http://djangosn-ps.org/sn-ps/1303/)。

def clean_content(self):
   content = self.cleaned_data['content']
   content_type = content.content_type.split('/')[0]
    if content_type in settings.CONTENT_TYPES:
       if content._size > settings.MAX_UPLOAD_SIZE:
          raise forms.ValidationError(_('Please keep filesize under %s. Current filesize %s') % (filesizeformat(settings.MAX_UPLOAD_SIZE), filesizeformat(content._size)))
    else:
        raise forms.ValidationError(_('File type is not supported'))
    return content

这里的潜在问题是

1) 此代码适用于 FileField,而不是 ImageField。我知道 ImageField 是 FileField 的子类,所以我认为这不是问题。这是真的吗?

2)整个 HttpRequest 请求在验证之前被读取(所以大文件仍然是一个问题)。另外,文件是否仍然写入 tmp,即使它引发了验证错误?

最后,您还会注意到此表单验证尝试过滤内容类型。我认为这几乎毫无价值,因为它只是查看扩展,很容易被欺骗。这也公平吗?

我知道这个问题有点漫无边际,但它是一个棘手且分散的主题(至少对我而言)

【问题讨论】:

    标签: django file django-models file-upload


    【解决方案1】:

    我知道你可以设置 FILE_UPLOAD_MAX_MEMORY_SIZE 在 设置.py。如果文件大于 此尺寸已上传,已写入 tmp 目录中的磁盘。这样做 几乎处理事情?将巨大 图片仍然影响我的网站 性能怎么样?

    取决于您所说的“句柄”。它将阻止处理上传的进程将整个文件读入内存并耗尽服务器的资源。它仍然会成功上传,您仍然会保存一个“大”文件。我认为这可能会影响您网站的性能,因为您要将服务器进程与上传相关联,上传需要更长的时间才能完成,因为它会撞到磁盘,这相对较慢。

    我见过的另一种选择是 配置 max_upload_size apache,其中(似乎)包含 在 php.ini 中。听起来对吗?是 可取吗?

    有一种方法可以在 apache 中限制请求的大小,但不是通过该设置。 php.ini 中的任何内容都特定于 PHP,与 Django 无关。您正在寻找 apache 的 LimitRequestBody 指令。

    这里的问题是关于你想要完成什么。您是否只想限制站点存储的文件的大小,而不关心它们是否实际上传(您不关心带宽使用情况)?如果是这样,那么您可以走表单验证路线,以便向您的用户呈现更好的错误。

    但是,如果您确实关心大型上传使用的带宽,并且想要停止以 N MB 上传任何文件,那么您应该考虑使用类似 QuotaUploadHandler 的东西或通过您的网络服务器设置限制(请参见上面的 LimitRequestBody)。如果您使用上传处理程序,则需要测试引发 StopUpload 异常时的行为——在File Uploads 文档的“receive_data_chunk”方法中有一条关于它的小注释。如果您选择让 apache 在达到一定大小后停止上传,您最终可能会向超过该限制的用户显示一些相当难看的错误页面。

    【讨论】:

    • 嘿 shadfc,这是一个很好的答案。我找不到 LimitRequestBody。我的想法是,我将使用一定大小的表单验证,然后为异常大的文件实现 LRB。
    • @brendan:这可能是最好的。我对该 QuotaUploadHandler 进行了快速测试,似乎没有办法处理由此引发的错误——你只会收到连接重置错误。所以让 apache 处理大的可能是最好的,因为它们会得到更具体的错误消息。太糟糕了,您必须使用网络服务器来实现此功能。在 Django 中处理表单错误会很棒,但这可能是一个白日梦。
    【解决方案2】:

    试试下面的代码,

    from django.core.exceptions import ValidationError
    def validate_image(fieldfile_obj):
            filesize = fieldfile_obj.file.size
            megabyte_limit = 2.0
            if filesize > megabyte_limit*1024*1024:
                raise ValidationError("Max file size is %sMB" % str(megabyte_limit))
    
    class User(models.Model):
        avatar = models.ImageField("Avatar", upload_to=upload_logo_to,validators=[validate_image], blank=True, null=True,help_text='Maximum file size allowed is 2Mb')
    

    【讨论】:

      猜你喜欢
      • 2015-04-02
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 2016-05-13
      • 2017-10-18
      • 2011-04-30
      • 1970-01-01
      • 2014-01-11
      相关资源
      最近更新 更多