summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManatsawin Hanmongkolchai <manatsawin+git@gmail.com>2017-05-28 14:05:21 +0700
committerTim Graham <timograham@gmail.com>2017-06-01 10:13:23 -0400
commita0c07d77fc313388c72a17cd59411265069f037f (patch)
tree6ca6565eb41de7db58122fe41cc853667ee83a76
parent6bb3b2bff4bca24896023758a720f16fa6b1e2bb (diff)
downloaddjango-a0c07d77fc313388c72a17cd59411265069f037f.tar.gz
Fixed #28242 -- Moved ImageField file extension validation to the form field.
-rw-r--r--django/db/models/fields/files.py2
-rw-r--r--django/forms/fields.py1
-rw-r--r--docs/releases/1.11.2.txt4
-rw-r--r--docs/releases/1.11.txt1
-rw-r--r--tests/forms_tests/field_tests/test_imagefield.py11
-rw-r--r--tests/model_fields/test_imagefield.py8
-rw-r--r--tests/model_forms/models.py11
-rw-r--r--tests/model_forms/tests.py20
8 files changed, 47 insertions, 11 deletions
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index cbd0386435..d14da97cce 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -6,7 +6,6 @@ from django.core import checks
from django.core.files.base import File
from django.core.files.images import ImageFile
from django.core.files.storage import default_storage
-from django.core.validators import validate_image_file_extension
from django.db.models import signals
from django.db.models.fields import Field
from django.utils.translation import gettext_lazy as _
@@ -355,7 +354,6 @@ class ImageFieldFile(ImageFile, FieldFile):
class ImageField(FileField):
- default_validators = [validate_image_file_extension]
attr_class = ImageFieldFile
descriptor_class = ImageFileDescriptor
description = _("Image")
diff --git a/django/forms/fields.py b/django/forms/fields.py
index a4132d8f33..d665606745 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -591,6 +591,7 @@ class FileField(Field):
class ImageField(FileField):
+ default_validators = [validators.validate_image_file_extension]
default_error_messages = {
'invalid_image': _(
"Upload a valid image. The file you uploaded was either not an "
diff --git a/docs/releases/1.11.2.txt b/docs/releases/1.11.2.txt
index e595d796ee..ed7753a74f 100644
--- a/docs/releases/1.11.2.txt
+++ b/docs/releases/1.11.2.txt
@@ -58,3 +58,7 @@ Bugfixes
* Fixed a regression where ``file_move_safe()`` crashed when moving files to a
CIFS mount (:ticket:`28170`).
+
+* Moved the ``ImageField`` file extension validation added in Django 1.11 from
+ the model field to the form field to reallow the use case of storing images
+ without an extension (:ticket:`28242`).
diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt
index 05c925259f..a6955d1460 100644
--- a/docs/releases/1.11.txt
+++ b/docs/releases/1.11.txt
@@ -327,6 +327,7 @@ Models
* :class:`~django.db.models.ImageField` now has a default
:data:`~django.core.validators.validate_image_file_extension` validator.
+ (This validator moved to the form field in :doc:`Django 1.11.2 <1.11.2>`.)
* Added support for time truncation to
:class:`~django.db.models.functions.datetime.Trunc` functions.
diff --git a/tests/forms_tests/field_tests/test_imagefield.py b/tests/forms_tests/field_tests/test_imagefield.py
index 6fb4bed03c..0a0f60440e 100644
--- a/tests/forms_tests/field_tests/test_imagefield.py
+++ b/tests/forms_tests/field_tests/test_imagefield.py
@@ -2,7 +2,7 @@ import os
import unittest
from django.core.files.uploadedfile import SimpleUploadedFile
-from django.forms import ImageField
+from django.forms import ImageField, ValidationError
from django.test import SimpleTestCase
try:
@@ -55,3 +55,12 @@ class ImageFieldTest(SimpleTestCase):
self.assertIsNone(uploaded_file.content_type)
finally:
Image.register_mime(BmpImageFile.format, 'image/bmp')
+
+ def test_file_extension_validation(self):
+ f = ImageField()
+ img_path = get_img_path('filepath_test_files/1x1.png')
+ with open(img_path, 'rb') as img_file:
+ img_data = img_file.read()
+ img_file = SimpleUploadedFile('1x1.txt', img_data)
+ with self.assertRaisesMessage(ValidationError, "File extension 'txt' is not allowed."):
+ f.clean(img_file)
diff --git a/tests/model_fields/test_imagefield.py b/tests/model_fields/test_imagefield.py
index 3a86d3daf5..50af786f5a 100644
--- a/tests/model_fields/test_imagefield.py
+++ b/tests/model_fields/test_imagefield.py
@@ -2,7 +2,7 @@ import os
import shutil
from unittest import skipIf
-from django.core.exceptions import ImproperlyConfigured, ValidationError
+from django.core.exceptions import ImproperlyConfigured
from django.core.files import File
from django.core.files.images import ImageFile
from django.test import TestCase
@@ -130,12 +130,6 @@ class ImageFieldTests(ImageFieldTestMixin, TestCase):
self.assertEqual(hash(p1_db.mugshot), hash(p1.mugshot))
self.assertIs(p1_db.mugshot != p1.mugshot, False)
- def test_validation(self):
- p = self.PersonModel(name="Joan")
- p.mugshot.save("shot.txt", self.file1)
- with self.assertRaisesMessage(ValidationError, "File extension 'txt' is not allowed."):
- p.full_clean()
-
def test_instantiate_missing(self):
"""
If the underlying file is unavailable, still create instantiate the
diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py
index 6e08eaec71..aecbeb18f3 100644
--- a/tests/model_forms/models.py
+++ b/tests/model_forms/models.py
@@ -192,6 +192,17 @@ try:
def __str__(self):
return self.description
+
+ class NoExtensionImageFile(models.Model):
+ def upload_to(self, filename):
+ return 'tests/no_extension'
+
+ description = models.CharField(max_length=20)
+ image = models.ImageField(storage=temp_storage, upload_to=upload_to)
+
+ def __str__(self):
+ return self.description
+
except ImportError:
test_images = False
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index 6520e54d06..e636d212d8 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -32,7 +32,7 @@ from .models import (
)
if test_images:
- from .models import ImageFile, OptionalImageFile
+ from .models import ImageFile, OptionalImageFile, NoExtensionImageFile
class ImageFileForm(forms.ModelForm):
class Meta:
@@ -44,6 +44,11 @@ if test_images:
model = OptionalImageFile
fields = '__all__'
+ class NoExtensionImageFileForm(forms.ModelForm):
+ class Meta:
+ model = NoExtensionImageFile
+ fields = '__all__'
+
class ProductForm(forms.ModelForm):
class Meta:
@@ -2461,6 +2466,19 @@ class FileAndImageFieldTests(TestCase):
self.assertEqual(instance.image.name, 'foo/test4.png')
instance.delete()
+ # Editing an instance that has an image without an extension shouldn't
+ # fail validation. First create:
+ f = NoExtensionImageFileForm(
+ data={'description': 'An image'},
+ files={'image': SimpleUploadedFile('test.png', image_data)},
+ )
+ self.assertTrue(f.is_valid())
+ instance = f.save()
+ self.assertEqual(instance.image.name, 'tests/no_extension')
+ # Then edit:
+ f = NoExtensionImageFileForm(data={'description': 'Edited image'}, instance=instance)
+ self.assertTrue(f.is_valid())
+
class ModelOtherFieldTests(SimpleTestCase):
def test_big_integer_field(self):