Version 4 (modified by newacct, 14 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 'upload_to' not in kwargs:
            kwargs['upload_to'] = 'tmp'
        self.use_key = kwargs.get('use_key', False)
        if 'use_key' in kwargs:
            del kwargs['use_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(
                        dst = os.path.join(
                    basedir = os.path.join(
                    fromdir = os.path.join(
                    shutil.move(fromdir, basedir)
                    setattr(instance, self.attname, dst)

    def db_type(self):
        """Required by Django for ORM."""
        return 'varchar(200)'

Back to Top