Accept Only Specific File Types in Django
There are times that we only have to accept specific file types and limit file size in our file uploads. This time, I am going to show simple steps to make a FileField accept only specific file types.
Assuming that we already have a working model, views and template(s) are already working.
Step 1:
Create a file and name it formatChecker.py. This is the code for 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") 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
We are now done with step 1. Basically, what formatChecker.py does is it overrides the FileField class. What that snippet does is it checks the file type of the file and checks the file size during the process of form validation. It returns error messages if a user uploaded an invalid file.
Step 2:
Change your field “FileField” to “ContentTypeRestrictedFileField”.
To make things more clear, I’ll show you an example.
Example:
class Archive(models.Model): title = models.CharField(max_length=245) # some other fields here attached_file = ContentTypeRestrictedFileField(upload_to='uploads/', content_types=['application/msword', 'application/pdf', 'application/vnd.oasis.opendocument.text'],max_upload_size=5242880,blank=True, null=True)
For the first value of the parameter of ContentTypeRestrictedFileField, “upload_to”, this is where the file goes when uploaded. The second value, “content_types”, is a list of accepted file types. The third value is the allowed maximum size of the file.
That’s it. We can now restrict file types that we do not want to be uploaded.