Version 1 (modified by 16 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' % self.id
Based closely on: http://scottbarnham.com/blog/2007/07/31/uploading-images-to-a-dynamic-path-with-django/ Later updated for newforms-admin by jamstooks: http://pandemoniumillusion.wordpress.com/2008/08/06/django-imagefield-and-filefield-dynamic-upload-path-in-newforms-admin/ """ 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:
del(kwargsuse_key)
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), instance.id, m.groups()[0]
)
else:
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) instance.save()
def db_type(self):
"""Required by Django for ORM.""" return 'varchar(200)'