Skip to content

Instantly share code, notes, and snippets.

@pawelszydlo
Last active August 29, 2015 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pawelszydlo/8745512 to your computer and use it in GitHub Desktop.
Save pawelszydlo/8745512 to your computer and use it in GitHub Desktop.
Django Image field with thumbnail.
from django.db.models import ImageField
from django.db.models import signals
from django.db.models.fields.files import ImageFieldFile
from PIL import Image
import os
def name_thumb(str):
""" Function for generating thumbnail name from original file. """
parts = str.split(u'.')
parts[-2]+=u'_thumb'
return u'.'.join(parts)
class ImageWithThumbFieldFile(ImageFieldFile):
""" Extension to file field. """
def get_thumb_url(self):
try: # hack to check if file was passed
self.file
except:
return
return name_thumb(u"%s"%self)
thumb_url = property(get_thumb_url)
class ImageWithThumbField(ImageField):
""" Model field for keeping a thumbnail next to actual image """
attr_class = ImageWithThumbFieldFile
def db_type(self, connection):
return 'Varchar(255)'
def __init__(self, verbose_name=None, name=None, twidth=120, theight=80, **kwargs):
self.twidth, self.theight = twidth, theight
super(ImageWithThumbField, self).__init__(verbose_name=verbose_name, name=name,**kwargs)
def _save(self,**kwargs):
image = getattr(kwargs['instance'], self.attname)
try: # hack to check if file was passed
image.file
except:
return
thumb_path = name_thumb(image.path)
if os.path.exists(thumb_path) and os.path.getmtime(image.path) > os.path.getmtime(thumb_path): #obsolete?
os.unlink(thumb_path)
if not os.path.exists(thumb_path):
image = Image.open(image.path)
image.thumbnail([self.twidth, self.theight], Image.ANTIALIAS)
try:
image.save(thumb_path, image.format, quality=90, optimize=1)
except:
image.save(thumb_path, image.format, quality=90)
def _delete(self,**kwargs):
image = getattr(kwargs['instance'], self.attname)
try: # hack to check if file was passed
image.file
except:
return
if image.file:
thumb_path = name_thumb(image.path)
try:
os.unlink(image.path)
os.unlink(thumb_path)
except OSError:
pass
def contribute_to_class(self, cls, name):
super(ImageWithThumbField, self).contribute_to_class(cls, name)
signals.post_save.connect(self._save, cls, True)
signals.pre_delete.connect(self._delete, cls, True)
def get_internal_type(self):
return 'ImageField'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment