Django File upload size limit
I have a form in my django app where users can upload files.
How can i set a limit to the uploaded file size so that if a user uploads a file larger than my limit the form won't be valid and it will throw an error?
Solution 1:
You can use this snippet formatChecker. What it does is
it lets you specify what file formats are allowed to be uploaded.
and lets you set the limit of file size of the file to be uploaded.
First. Create a file named formatChecker.py inside the app where the you have the model that has the FileField that you want to accept a certain file type.
This is your 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", 0)
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
Second. In your models.py, add this:
from formatChecker import ContentTypeRestrictedFileField
Then instead of using 'FileField', use this 'ContentTypeRestrictedFileField'.
Example:
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)
You can change the value of 'max_upload_size' to the limit of file size that you want. You can also change the values inside the list of 'content_types' to the file types that you want to accept.
Solution 2:
another solution is using validators
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.')
then in your form with the File field you have something like this
image = forms.FileField(required=False, validators=[file_size])
Solution 3:
This code might help:
# 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
Taken from: Django Snippets - Validate by file content type and size
Solution 4:
I believe that django form receives file only after it was uploaded completely.That's why if somebody uploads 2Gb file, you're much better off with web-server checking for size on-the-fly.
See this mail thread for more info.
Solution 5:
Server side
My favourite method of checking whether a file is too big server-side is ifedapo olarewaju's answer using a validator.
Client side
The problem with only having server-side validation is that the validation only happens after the upload is complete. Imagine, uploading a huge file, waiting for ages, only to be told afterwards that the file is too big. Wouldn't it be nicer if the browser could let me know beforehand that the file is too big?
Well, there is a way to this client side, using HTML5 File API!
Here's the required Javascript (depending on 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;
}
}
});
Of course, you still need server-side validation, to protect against malicious input, and users that don't have Javascript enabled.