Version 1 (modified by Richard <richard@…>, 7 years ago) (diff)


from django.db.models import ImageField, FileField, signals from django.conf import settings import shutil, os, glob, re

class CustomImageField(ImageField):

"""Allows model instance to specify upload_to dynamically.

Model class should have a method like:

def get_upload_to(self, attname):

return 'path/to/%d' %

Based closely on: Later updated for newforms-admin by jamstooks: """ def init(self, *args, kwargs):

if not 'upload_to' in kwargs:

kwargsupload_to? = 'tmp'

self.use_key = kwargs.get('use_key', False) if 'use_key' in kwargs:


super(CustomImageField, self).init(*args, kwargs)

def contribute_to_class(self, cls, name):

"""Hook up events so we can access the instance.""" super(CustomImageField, self).contribute_to_class(cls, name) signals.post_save.connect(self._move_image, sender=cls)

def _move_image(self, instance=None, kwargs):


Function to move the temporarily uploaded image to a more suitable directory using the model's get_upload_to() method.

""" if hasattr(instance, 'get_upload_to'):

src = getattr(instance, self.attname) if src:

m = re.match(r"%s/(.*)" % self.upload_to, src) if m:

if self.use_key:

dst = os.path.join(

instance.get_upload_to(self.attname),, m.groups()[0]



dst = os.path.join(

instance.get_upload_to(self.attname), m.groups()[0]


basedir = os.path.join(

settings.MEDIA_ROOT, os.path.dirname(dst)

) fromdir = os.path.join(

settings.MEDIA_ROOT, src

) shutil.move(fromdir, basedir) setattr(instance, self.attname, dst)

def db_type(self):

"""Required by Django for ORM.""" return 'varchar(200)'

Back to Top