Login

Custom FileField with content type and size validation

Author:
nemesis
Posted:
September 24, 2010
Language:
Python
Version:
1.2
Tags:
forms validation upload filefield file content-type max_upload_size
Score:
1 (after 3 ratings)
 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
# extra.py in yourproject/app/

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

        return data

More like this

  1. Validate by file content type and size by macmichael01 7 years, 7 months ago
  2. Class based FileTypeValidator by jmsfwk 3 months ago
  3. Database file storage by powerfox 7 years, 7 months ago
  4. File Mimetype Validator (Using python-magic) by BHSPitMonkey 2 years, 5 months ago
  5. Aggiornare i Content Types e i Permessi del Model di una Tabella nell Admin by dario.agliottone 4 years, 3 months ago

Comments

nemesis (on September 27, 2010):
<p>Thanks for the info.</p> <p>Is not exactly a duplicated of 1303, even if I used the main part of that. 1303 is a custom validation while this is a custom file field that can be used in the admin too.</p> <p>How would you advice to implement the method you linked?</p>

#

gsakkis (on September 27, 2010):
<p>I'd love to be proven wrong but I believe there is no way to get a nice validation error without uploading the whole file; otherwise the browser throws "The connection to the server was reset while the page was loading" on Firefox (or "Error 101 (net::ERR_CONNECTION_RESET): Unknown error" on Chrome).</p>

#

nemesis (on September 30, 2010):
<p>So would it be possible then to add a line in the end that deletes the file? I'll try it out..</p>

#

nemesis (on September 30, 2010):
<p>The files is stored only in the temporary directory.</p> <p>I think it's a good solution to use both this filefield and set FILE_UPLOAD_MAX_MEMORY_SIZE in your settings.py file so it allows a size that is slight larger than the model field.</p>

#

byroncorrales (on October 1, 2010):
<p>For get it work with south migrations I had to changed some lines...</p> <pre>def __init__(self, content_types=None, max_upload_size=None, **kwargs): self.content_types = content_types self.max_upload_size = max_upload_size super(ContentTypeRestrictedFileField, self).__init__(**kwargs) </pre> <p>And adding the specific rule for south and the end of the file</p> <pre>from south.modelsinspector import add_introspection_rules add_introspection_rules([], ["^app\.extra\.ContentTypeRestrictedFileField"]) </pre>

#

eos87 (on October 4, 2010):
<p>it works for me!, but i recommend add the project name to the instrospection_rule path, something like this:</p> <p>from south.modelsinspector import add_introspection_rules add_introspection_rules([], ["^project_name.app.extra.ContentTypeRestrictedFileField"])</p>

#

eos87 (on October 4, 2010):
<p>oops! i forgot the slashes!!</p> <pre>from south.modelsinspector import add_introspection_rules add_introspection_rules([], ["^project_name\.app\.extra\.ContentTypeRestrictedFileField"]) </pre>

#

nemesis (on October 30, 2010):
<p>@gsakkis</p> <p>I designed this field to use it in the admin so i'm not worried about 1GB file because the users are already trusted.</p> <p>For who's worried about huge files: configure the max upload limit in apache.</p>

#

sv1jsb (on February 18, 2011):
<p>I am new in Django but I would like to ask this, reading your code.</p> <p>You import FileField from models but FileField in models doesn't have a clean method.</p> <p>FileField from forms have one.</p> <p>You have been using this snippet as it is and it worked without a problem?</p>

#

dokterbob (on August 31, 2011):
<p>A new & dusted off version, checking minimum size, maximum size, matching extensions and mime types.</p> <p>https://gist.github.com/1183767</p>

#

AguirreLORETTA27 (on March 14, 2012):
<p>Some time ago, I needed to buy a building for my business but I didn't have enough cash and could not purchase anything. Thank heaven my father proposed to try to take the loans at banks. Thus, I acted so and was satisfied with my collateral loan. </p>

#

Please login first before commenting.