summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--django/db/models/fields/files.py2
-rw-r--r--tests/modeltests/model_forms/models.py127
-rw-r--r--tests/modeltests/model_forms/test2.pngbin0 -> 2072 bytes
4 files changed, 103 insertions, 27 deletions
diff --git a/AUTHORS b/AUTHORS
index 210f52c5a5..c89fd5ccac 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -35,6 +35,7 @@ answer newbie questions, and generally made Django that much better:
Jeff Anderson <jefferya@programmerq.net>
Marian Andre <django@andre.sk>
Andreas
+ Victor Andrée
andy@jadedplanet.net
Fabrice Aneche <akh@nobugware.com>
ant9000@netwise.it
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index 878d09c976..f9bfc9d03f 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -132,7 +132,7 @@ class FileDescriptor(object):
# have the FieldFile interface added to them
file_copy = copy.copy(file)
file_copy.__class__ = type(file.__class__.__name__,
- (file.__class__, FieldFile), {})
+ (file.__class__, self.field.attr_class), {})
file_copy.instance = instance
file_copy.field = self.field
file_copy.storage = self.field.storage
diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py
index 6ef44d909b..e12363cf3c 100644
--- a/tests/modeltests/model_forms/models.py
+++ b/tests/modeltests/model_forms/models.py
@@ -98,26 +98,47 @@ class TextFile(models.Model):
def __unicode__(self):
return self.description
-class ImageFile(models.Model):
- def custom_upload_path(self, filename):
- path = self.path or 'tests'
- return '%s/%s' % (path, filename)
+try:
+ # If PIL is available, try testing ImageFields.
+ # Checking for the existence of Image is enough for CPython, but
+ # for PyPy, you need to check for the underlying modules
+ # If PIL is not available, ImageField tests are omitted.
+ from PIL import Image, _imaging
+ test_images = True
- description = models.CharField(max_length=20)
- try:
- # If PIL is available, try testing PIL.
- # Checking for the existence of Image is enough for CPython, but
- # for PyPy, you need to check for the underlying modules
- # If PIL is not available, this test is equivalent to TextFile above.
- from PIL import Image, _imaging
- image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path)
- except ImportError:
- image = models.FileField(storage=temp_storage, upload_to=custom_upload_path)
- path = models.CharField(max_length=16, blank=True, default='')
+ class ImageFile(models.Model):
+ def custom_upload_path(self, filename):
+ path = self.path or 'tests'
+ return '%s/%s' % (path, filename)
+
+ description = models.CharField(max_length=20)
+ image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path,
+ width_field='width', height_field='height')
+ width = models.IntegerField(editable=False)
+ height = models.IntegerField(editable=False)
+ path = models.CharField(max_length=16, blank=True, default='')
- def __unicode__(self):
- return self.description
+ def __unicode__(self):
+ return self.description
+
+ class OptionalImageFile(models.Model):
+ def custom_upload_path(self, filename):
+ path = self.path or 'tests'
+ return '%s/%s' % (path, filename)
+
+ description = models.CharField(max_length=20)
+ image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path,
+ width_field='width', height_field='height',
+ blank=True, null=True)
+ width = models.IntegerField(editable=False, null=True)
+ height = models.IntegerField(editable=False, null=True)
+ path = models.CharField(max_length=16, blank=True, default='')
+ def __unicode__(self):
+ return self.description
+except ImportError:
+ test_images = False
+
class CommaSeparatedInteger(models.Model):
field = models.CommaSeparatedIntegerField(max_length=20)
@@ -1056,7 +1077,10 @@ True
# Delete the current file since this is not done by Django.
>>> instance.file.delete()
>>> instance.delete()
+"""}
+if test_images:
+ __test__['API_TESTS'] += """
# ImageField ###################################################################
# ImageField and FileField are nearly identical, but they differ slighty when
@@ -1068,6 +1092,7 @@ True
... model = ImageFile
>>> image_data = open(os.path.join(os.path.dirname(__file__), "test.png"), 'rb').read()
+>>> image_data2 = open(os.path.join(os.path.dirname(__file__), "test2.png"), 'rb').read()
>>> f = ImageFileForm(data={'description': u'An image'}, files={'image': SimpleUploadedFile('test.png', image_data)})
>>> f.is_valid()
@@ -1077,6 +1102,10 @@ True
>>> instance = f.save()
>>> instance.image
<...FieldFile: tests/test.png>
+>>> instance.width
+16
+>>> instance.height
+16
# Delete the current file since this is not done by Django.
>>> instance.image.delete()
@@ -1089,8 +1118,12 @@ True
>>> instance = f.save()
>>> instance.image
<...FieldFile: tests/test.png>
+>>> instance.width
+16
+>>> instance.height
+16
-# Edit an instance that already has the image defined in the model. This will not
+# Edit an instance that already has the (required) image defined in the model. This will not
# save the image again, but leave it exactly as it is.
>>> f = ImageFileForm(data={'description': u'Look, it changed'}, instance=instance)
@@ -1101,6 +1134,10 @@ True
>>> instance = f.save()
>>> instance.image
<...FieldFile: tests/test.png>
+>>> instance.height
+16
+>>> instance.width
+16
# Delete the current image since this is not done by Django.
@@ -1108,23 +1145,31 @@ True
# Override the file by uploading a new one.
->>> f = ImageFileForm(data={'description': u'Changed it'}, files={'image': SimpleUploadedFile('test2.png', image_data)}, instance=instance)
+>>> f = ImageFileForm(data={'description': u'Changed it'}, files={'image': SimpleUploadedFile('test2.png', image_data2)}, instance=instance)
>>> f.is_valid()
True
>>> instance = f.save()
>>> instance.image
<...FieldFile: tests/test2.png>
+>>> instance.height
+32
+>>> instance.width
+48
# Delete the current file since this is not done by Django.
>>> instance.image.delete()
>>> instance.delete()
->>> f = ImageFileForm(data={'description': u'Changed it'}, files={'image': SimpleUploadedFile('test2.png', image_data)})
+>>> f = ImageFileForm(data={'description': u'Changed it'}, files={'image': SimpleUploadedFile('test2.png', image_data2)})
>>> f.is_valid()
True
>>> instance = f.save()
>>> instance.image
<...FieldFile: tests/test2.png>
+>>> instance.height
+32
+>>> instance.width
+48
# Delete the current file since this is not done by Django.
>>> instance.image.delete()
@@ -1132,31 +1177,58 @@ True
# Test the non-required ImageField
->>> f = ImageFileForm(data={'description': u'Test'})
->>> f.fields['image'].required = False
+>>> class OptionalImageFileForm(ModelForm):
+... class Meta:
+... model = OptionalImageFile
+
+>>> f = OptionalImageFileForm(data={'description': u'Test'})
>>> f.is_valid()
True
>>> instance = f.save()
>>> instance.image
<...FieldFile: None>
+>>> instance.width
+>>> instance.height
+
+>>> f = OptionalImageFileForm(data={'description': u'And a final one'}, files={'image': SimpleUploadedFile('test3.png', image_data)}, instance=instance)
+>>> f.is_valid()
+True
+>>> instance = f.save()
+>>> instance.image
+<...FieldFile: tests/test3.png>
+>>> instance.width
+16
+>>> instance.height
+16
->>> f = ImageFileForm(data={'description': u'And a final one'}, files={'image': SimpleUploadedFile('test3.png', image_data)}, instance=instance)
+# Editing the instance without re-uploading the image should not affect the image or its width/height properties
+>>> f = OptionalImageFileForm(data={'description': u'New Description'}, instance=instance)
>>> f.is_valid()
True
>>> instance = f.save()
+>>> instance.description
+u'New Description'
>>> instance.image
<...FieldFile: tests/test3.png>
+>>> instance.width
+16
+>>> instance.height
+16
# Delete the current file since this is not done by Django.
>>> instance.image.delete()
>>> instance.delete()
->>> f = ImageFileForm(data={'description': u'And a final one'}, files={'image': SimpleUploadedFile('test3.png', image_data)})
+>>> f = OptionalImageFileForm(data={'description': u'And a final one'}, files={'image': SimpleUploadedFile('test4.png', image_data2)})
>>> f.is_valid()
True
>>> instance = f.save()
>>> instance.image
-<...FieldFile: tests/test3.png>
+<...FieldFile: tests/test4.png>
+>>> instance.width
+48
+>>> instance.height
+32
>>> instance.delete()
# Test callable upload_to behavior that's dependent on the value of another field in the model
@@ -1167,6 +1239,9 @@ True
>>> instance.image
<...FieldFile: foo/test4.png>
>>> instance.delete()
+"""
+
+__test__['API_TESTS'] += """
# Media on a ModelForm ########################################################
@@ -1355,4 +1430,4 @@ ValidationError: [u'Select a valid choice. z is not one of the available choices
# Clean up
>>> import shutil
>>> shutil.rmtree(temp_storage_dir)
-"""}
+"""
diff --git a/tests/modeltests/model_forms/test2.png b/tests/modeltests/model_forms/test2.png
new file mode 100644
index 0000000000..10702f75a1
--- /dev/null
+++ b/tests/modeltests/model_forms/test2.png
Binary files differ