From d6e77283e9ccdb3bf7cf1e2e4b7425f2b898fb24 Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Wed, 6 Jan 2016 08:42:35 -0500 Subject: [PATCH] Fixes #9: Validate file size before content type Aside from the fact that checking size is cheaper, this change fixes a misleading and confusing message described in issue #9, where a user uploading a MS Word .doc file which is too big is told incorrectly that the content type is wrong. The tests were changed to work (only) with Django 1.6 and above, which changed humanize to add a non-breaking space (\xa0) between a value and its unit. See this ticket for more details: https://code.djangoproject.com/ticket/20246 I tested with these dependencies along with Python 2.7.6: Django==1.6.11 python-magic==0.4.10 --- testing/tests.py | 6 +++--- validatedfile/fields.py | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/testing/tests.py b/testing/tests.py index 079e4fb..05a43a9 100644 --- a/testing/tests.py +++ b/testing/tests.py @@ -51,7 +51,7 @@ def test_form_invalid_size(self): self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(len(form.errors['the_file']), 1) - self.assertEqual(form.errors['the_file'][0], u'Files of size greater than 10.0 KB are not allowed. Your file is 14.2 KB') + self.assertEqual(form.errors['the_file'][0], u'Files of size greater than 10.0\xa0KB are not allowed. Your file is 14.2\xa0KB') def test_form_invalid_filetype(self): @@ -73,7 +73,7 @@ def test_form_invalid_filetype_and_size(self): self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(len(form.errors['the_file']), 1) - self.assertEqual(form.errors['the_file'][0], u'Files of type application/pdf are not supported.') + self.assertEqual(form.errors['the_file'][0], u'Files of size greater than 10.0\xa0KB are not allowed. Your file is 14.9\xa0KB') def test_form_fake_filetype(self): @@ -269,7 +269,7 @@ def test_form_quota_exceeded(self): self.assertEqual(len(form.errors), 1) self.assertEqual(len(form.errors['the_file']), 1) self.assertEqual(form.errors['the_file'][0], - u'Please keep the total uploaded files under 9.8 KB. With this file, the total would be 16.3 KB.') + u'Please keep the total uploaded files under 9.8\xa0KB. With this file, the total would be 16.3\xa0KB.') element.the_file.delete() element.delete() diff --git a/validatedfile/fields.py b/validatedfile/fields.py index 0985c18..270f3e3 100644 --- a/validatedfile/fields.py +++ b/validatedfile/fields.py @@ -17,6 +17,13 @@ def clean(self, *args, **kwargs): data = super(ValidatedFileField, self).clean(*args, **kwargs) file = data.file + if self.max_upload_size and hasattr(file, '_size'): + if file._size > self.max_upload_size: + raise forms.ValidationError( + _('Files of size greater than %(max_size)s are not allowed. Your file is %(current_size)s') % + {'max_size': filesizeformat(self.max_upload_size), 'current_size': filesizeformat(file._size)} + ) + if self.content_types: uploaded_content_type = getattr(file, 'content_type', '') @@ -35,13 +42,6 @@ def clean(self, *args, **kwargs): _('Files of type %(type)s are not supported.') % {'type': content_type_magic} ) - if self.max_upload_size and hasattr(file, '_size'): - if file._size > self.max_upload_size: - raise forms.ValidationError( - _('Files of size greater than %(max_size)s are not allowed. Your file is %(current_size)s') % - {'max_size': filesizeformat(self.max_upload_size), 'current_size': filesizeformat(file._size)} - ) - return data