2011-04-24 61 views
1

我的网站依靠用户上传的图像文件。我想限制max_upload_size。Django图片上传中...阻止巨大文件上传

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

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

另一个步骤涉及检查文件对象的属性。我已经浏览了这个snipet(http://djangosnippets.org/snippets/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,即使它引发验证错误?

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

我知道这个问题有点散漫,但它(至少对我来说)是一个艰难和扩散主题

回答

4

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

取决于你的意思是“处理”。它将使处理上载的进程不会将整个文件读入内存并使用服务器的资源。它仍然会成功上传,并且您仍然可以保存“大型”文件。我认为这可能会影响您的网站的性能,因为您要保持一个服务器进程与上传完成,因为它要打到相对较慢的磁盘,所以需要更长时间才能完成。我见过

一种选择是 配置 阿帕奇,这(似乎)被包含在php.ini 的max_upload_size。这听起来是对的吗?它是可取的 ?

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

这里的问题是关于你想要完成的。你只想限制你网站存储的文件的大小,但是你不关心它们是否真的被上传了(你不关心你的带宽使用情况)?如果是这样,那么你可以去表单验证路线,以向用户展示更好的错误。

但是,如果您关心大型上传使用的带宽,并且您想停止以NMB上传任何文件,那么您应该考虑使用类似QuotaUploadHandler或通过您的网络服务器设置限制(请参阅上面的LimitRequestBody)。如果使用上传处理程序,则需要测试引发StopUpload异常时的行为 - File Uploads文档中的“receive_data_chunk”方法中有一个小小的评论。如果你选择让apache在一定大小之后停止上传,你最终可能会向超出限制的用户显示一些相当丑陋的错误页面。

+0

嘿shadfc,这是一个伟大的答案。我找不到LimitRequestBody。我的想法是,我将使用表单验证达到一定的大小,然后为奇怪的大文件实施LRB。 – Ben 2011-04-24 12:53:31

+0

@ brendan:这可能是最好的。我对QuotaUploadHandler做了一个快速测试,似乎没有办法处理由此引发的错误 - 您只会收到连接重置错误。所以让apache处理巨大的可能是最好的,因为他们会得到更具体的错误信息。这太糟糕了,你必须将这个功能用于网络服务器。在Django中处理这个表单错误会很棒,但这可能是一个梦想。 – shadfc 2011-04-25 19:26:02

+0

QuotaUploadHandler的链接已死亡 – 2016-06-21 07:57:19

1

尝试下面的代码,

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')