Login

FileField with file extension whitelist

Author:
jedie
Posted:
August 14, 2008
Language:
Python
Version:
.96
Tags:
forms filefield
Score:
2 (after 6 ratings)

A simple FileField with a addition file extension whitelist. Raised ValidationError("Not allowed filetype!") if a filename contains a extension witch is not in the whitelist.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import os

from django import forms


class ExtFileField(forms.FileField):
    """
    Same as forms.FileField, but you can specify a file extension whitelist.
    
    >>> from django.core.files.uploadedfile import SimpleUploadedFile
    >>>
    >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
    >>>
    >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
    >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
    >>>
    >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
    Traceback (most recent call last):
    ...
    ValidationError: [u'Not allowed filetype!']
    """
    def __init__(self, *args, **kwargs):
        ext_whitelist = kwargs.pop("ext_whitelist")
        self.ext_whitelist = [i.lower() for i in ext_whitelist]

        super(ExtFileField, self).__init__(*args, **kwargs)

    def clean(self, *args, **kwargs):
        data = super(ExtFileField, self).clean(*args, **kwargs)
        filename = data.name
        ext = os.path.splitext(filename)[1]
        ext = ext.lower()
        if ext not in self.ext_whitelist:
            raise forms.ValidationError("Not allowed filetype!")

#-------------------------------------------------------------------------

if __name__ == "__main__":
    import doctest, datetime
    doctest.testmod()

More like this

  1. Whitelisted overwriting FileSystemStorage by nickma_at 3 years, 6 months ago
  2. FileField mismatches by depaolim 2 months, 3 weeks ago
  3. Amazon S3 Enabled FileField and ImageField (with Boto) by natebeacham 4 years, 11 months ago
  4. Custom FileField with content type and size validation by nemesis 4 years, 5 months ago
  5. Add a "remove file" field for Image- or FileFields by rodrigoc 6 years, 7 months ago

Comments

Finity (on May 23, 2011):

This will through an AttributeError if required=False. (Due to trying to access data.name when data will be None if required == False).

I rewrote it as [HTML_REMOVED] def clean(self, *args, kwargs): data = super(ExtFileField, self).clean(*args, kwargs)

    if data is None:
        if self.required:
            raise ValidationError("This file is required")
        else:
            return
    else:
        filename = data.name
        ext = os.path.splitext(filename)[1]
        ext = ext.lower()
        if ext not in self.ext_whitelist:
            file_types = ", ".join([i for i in self.ext_whitelist])
            error = "Only allowed file types are: %s" % file_types
            raise forms.ValidationError(error)

[HTML_REMOVED]

Hopefully I'm correct on this one.

#

Finity (on May 23, 2011):

s/through/raise an AttributeError exception. :)

Couldn't figure out how to keep djangosnippets from mucking up my code, but hopefully you get the point.

#

computmaxer (on February 19, 2013):

This snippet does not account for a field that is not required, and also does not return data so it does not get cleaned correctly.

The superclass will return False for data if the file has been cleared and the field is not required.

Here's a revised clean method for this snippet:

```

def clean(self, *args, **kwargs):
    data = super(ExtFileField, self).clean(*args, **kwargs)
    if data:
        filename = data.name
        ext = os.path.splitext(filename)[1]
        ext = ext.lower()
        if ext not in self.ext_whitelist:
            raise forms.ValidationError("Filetype not allowed! Filetypes allowed: " + ', '.join(self.ext_whitelist))
    return data

```

#

Please login first before commenting.