Djangofile upload大小限制

我有一个在我的Django应用程序,用户可以上传文件的窗体。
我怎样才能设置上传的文件大小的限制,以便如果用户上传大于我的限制的文件表单将无效,它会抛出一个错误?

此代码可能有助于:

# Add to your settings file CONTENT_TYPES = ['image', 'video'] # 2.5MB - 2621440 # 5MB - 5242880 # 10MB - 10485760 # 20MB - 20971520 # 50MB - 5242880 # 100MB 104857600 # 250MB - 214958080 # 500MB - 429916160 MAX_UPLOAD_SIZE = "5242880" #Add to a form containing a FileField and change the field names accordingly. from django.template.defaultfilters import filesizeformat from django.utils.translation import ugettext_lazy as _ from django.conf import settings 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 

取自: Django Snippets – 按文件内容types和大小进行validation

你可以使用这个片段formatChecker。 它是做什么的

  • 它允许您指定允许上传的文件格式。

  • 并让您设置要上传文件的文件大小限制。

第一。 在应用程序中创build一个名为formatChecker.py的文件,在该文件中具有您要接受某种文件types的FileField的模型。

这是你的formatChecker.py:

 from django.db.models import FileField from django.forms import forms from django.template.defaultfilters import filesizeformat from django.utils.translation import ugettext_lazy as _ class ContentTypeRestrictedFileField(FileField): """ Same as FileField, but you can specify: * content_types - list containing allowed content_types. Example: ['application/pdf', 'image/jpeg'] * max_upload_size - a number indicating the maximum file size allowed for upload. 2.5MB - 2621440 5MB - 5242880 10MB - 10485760 20MB - 20971520 50MB - 5242880 100MB 104857600 250MB - 214958080 500MB - 429916160 """ def __init__(self, *args, **kwargs): self.content_types = kwargs.pop("content_types") self.max_upload_size = kwargs.pop("max_upload_size") super(ContentTypeRestrictedFileField, self).__init__(*args, **kwargs) def clean(self, *args, **kwargs): data = super(ContentTypeRestrictedFileField, self).clean(*args, **kwargs) file = data.file try: content_type = file.content_type if content_type in self.content_types: if file._size > self.max_upload_size: raise forms.ValidationError(_('Please keep filesize under %s. Current filesize %s') % (filesizeformat(self.max_upload_size), filesizeformat(file._size))) else: raise forms.ValidationError(_('Filetype not supported.')) except AttributeError: pass return data 

第二。 在你的models.py中,添加这个:

 from formatChecker import ContentTypeRestrictedFileField 

然后,而不是使用“FileField”,使用这个“ContentTypeRestrictedFileField”。

例:

 class Stuff(models.Model): title = models.CharField(max_length=245) handout = ContentTypeRestrictedFileField(upload_to='uploads/', content_types=['video/x-msvideo', 'application/pdf', 'video/mp4', 'audio/mpeg', ],max_upload_size=5242880,blank=True, null=True) 

您可以将“max_upload_size”的值更改为所需的文件大小限制。 您还可以将“content_types”列表中的值更改为您要接受的文件types。

我相信,只有在完全上传之后,django表单才会收到文件。这就是为什么如果有人上传2Gb文件,那么使用networking服务器检查文件大小就可以了。

看到这个邮件主题了解更多信息。

另一个解决scheme是使用validation器

 from django.core.exceptions import ValidationError def file_size(value): # add this to some file where you can import it from limit = 2 * 1024 * 1024 if value.size > limit: raise ValidationError('File too large. Size should not exceed 2 MiB.') 

然后在你的forms与文件字段,你有这样的事情

 image = forms.FileField(required=False, validators=[file_size]) 

只是在这个线程中包含的片段的简短说明:

看看这个片段: http : //www.djangosnippets.org/snippets/1303/

这是非常有用的,但它包括一些小的错误。 更健壮的代码应该如下所示:

 # Add to your settings file CONTENT_TYPES = ['image', 'video'] # 2.5MB - 2621440 # 5MB - 5242880 # 10MB - 10485760 # 20MB - 20971520 # 50MB - 5242880 # 100MB - 104857600 # 250MB - 214958080 # 500MB - 429916160 MAX_UPLOAD_SIZE = "5242880" #Add to a form containing a FileField and change the field names accordingly. from django.template.defaultfilters import filesizeformat from django.utils.translation import ugettext_lazy as _ from django.conf import settings def clean_content(self): if content != None: content = self.cleaned_data['content'] content_type = content.content_type.split('/')[0] if content_type in settings.CONTENT_TYPES: if content._size > int(settings.MAX_UPLOAD_SIZE): raise forms.ValidationError(_(u'Please keep filesize under %s. Current filesize %s') % (filesizeformat(settings.MAX_UPLOAD_SIZE), filesizeformat(content._size))) else: raise forms.ValidationError(_(u'File type is not supported')) return content 

只有一些改进:

首先,我正在检测文件字段是否为空(无) – 没有它,Django将在Web浏览器中抛出exception。

接下来是在int(settings.MAX_UPLOAD_SIZE)中进行types转换,因为该设置值是一个string。 string不能用于比较数字。

最后但并非最不重要的一点,在Unicode ValidationError函数中,Unicode是前缀。

非常感谢你的这个片段!

如果有人正在寻找@angelo解决scheme的FormField变体,那么在这里

 from django import forms from django.template.defaultfilters import filesizeformat from django.utils.translation import ugettext_lazy as _ from django.core.exceptions import ValidationError class RestrictedFileField(forms.FileField): """ Same as FileField, but you can specify: * content_types - list containing allowed content_types. Example: ['application/pdf', 'image/jpeg'] * max_upload_size - a number indicating the maximum file size allowed for upload. 2.5MB - 2621440 5MB - 5242880 10MB - 10485760 20MB - 20971520 50MB - 5242880 100MB - 104857600 250MB - 214958080 500MB - 429916160 """ def __init__(self, *args, **kwargs): self.content_types = kwargs.pop("content_types") self.max_upload_size = kwargs.pop("max_upload_size") super(RestrictedFileField, self).__init__(*args, **kwargs) def clean(self, data, initial=None): file = super(RestrictedFileField, self).clean(data, initial) try: content_type = file.content_type if content_type in self.content_types: if file._size > self.max_upload_size: raise ValidationError(_('Please keep filesize under %s. Current filesize %s') % ( filesizeformat(self.max_upload_size), filesizeformat(file._size))) else: raise ValidationError(_('Filetype not supported.')) except AttributeError: pass return data 

然后创build一个表单

 class ImageUploadForm(forms.Form): """Image upload form.""" db_image = RestrictedFileField(content_types=['image/png', 'image/jpeg'], max_upload_size=5242880) 

服务器端

我最喜欢的检查文件是否太大服务器端的方法是使用validation器的ifedapo olarewaju的答案 。

客户端

只有服务器端validation的问题是validation只发生在上传完成后。 想象一下,上传一个巨大的文件,等待一段时间,然后才被告知该文件太大。 如果浏览器能够事先告诉我这个文件太大,会不会更好?

那么,有一种方法,这个客户端 ,使用HTML5的文件API

以下是所需的Javascript(取决于JQuery):

 $("form").submit(function() { if (window.File && window.FileReader && window.FileList && window.Blob) { var file = $('#id_file')[0].files[0]; if (file && file.size > 2 * 1024 * 1024) { alert("File " + file.name + " of type " + file.type + " is too big"); return false; } } }); 

当然,您仍然需要服务器端validation,以防止恶意input以及未启用Javascript的用户。

 from django.forms.utils import ErrorList class Mymodelform(forms.ModelForm): class Meta: model = Mymodel fields = '__all__' def clean(self):image = self.cleaned_data.get('image') # 5MB - 5242880 if org_image._size > 5242880: self._errors["image"] = ErrorList([u"Image too heavy."])