The following code takes an image after it gets saved and makes a thumbnail out of it:
class Image(models.Model):
image = models.ImageField(upload_to='images')
thumbnail = models.ImageField(upload_to='images/thumbnails', editable=False)
def save(self, *args, **kwargs):
super(Image, self).save(*args, **kwargs)
if self.image:
from PIL import Image as ImageObj
from cStringIO import StringIO
from django.core.files.uploadedfile import SimpleUploadedFile
try:
# thumbnail
THUMBNAIL_SIZE = (160, 160) # dimensions
image = ImageObj.open(self.image)
# Convert to RGB if necessary
if image.mode not in ('L', 'RGB'): image = image.convert('RGB')
# create a thumbnail + use antialiasing for a smoother thumbnail
image.thumbnail(THUMBNAIL_SIZE, ImageObj.ANTIALIAS)
# fetch image into memory
temp_handle = StringIO()
image.save(temp_handle, 'png')
temp_handle.seek(0)
# save it
file_name, file_ext = os.path.splitext(self.image.name.rpartition('/')[-1])
suf = SimpleUploadedFile(file_name + file_ext, temp_handle.read(), content_type='image/png')
self.thumbnail.save(file_name + '.png', suf, save=False)
except ImportError:
pass
It's working fine, the original image + the thumbnail are both being uploaded, and image is being assigned the correct path.
The only problem is thumbnail is not being assigned the path of the newly created thumbnail - it's empty in the database. I have read the documentation, and it looks like if I save the thumbnail with save=True it should fix my problem:
self.thumbnail.save(file_name + '.png', suf, save=True)
However, doing this is raising the following:
Django Version: 1.3.1
Exception Type: IOError
Exception Value:
cannot identify image file
I can't figure out what I'm doing wrong.
I have solved my problem simply by moving:
super(Image, self).save(*args, **kwargs)
to the end of def save(). I'm still not certain why it's happening this way, but my only explanation is that save() itself is persisting fields values to the database and hence it needs to be executed at the very end.
Try pass the actual file contents instead of the SimpleUploadedFile object:
self.thumbnail.save(file_name + '.png', temp_handle.read(), save=True)
https://docs.djangoproject.com/en/dev/ref/files/file/#additional-methods-on-files-attached-to-objects how to manually assign imagefield in Django Programmatically saving image to Django ImageField
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With