Nov
8
8
If you’re wondering how to override a name of a file you’re uploading to ImageField/FileField in Django, here’s one of the possible solutions:
Add this to your models.py
Python
-
from django.dispatch import dispatcher
-
import shutil, os, settings, re
-
-
class CustomImageField(models.ImageField):
-
"""
-
Model class should have a method like:
-
-
def personalize_name(self, field_attname):
-
return "path/to/file/%d.jpg" % self.id
-
-
"""
-
def contribute_to_class(self, cls, name):
-
super(CustomImageField, self).contribute_to_class(cls, name)
-
dispatcher.connect(self._save, models.signals.pre_save, sender=cls)
-
-
def _save(self, instance):
-
oldname = getattr(instance, self.attname)
-
extension = re.findall(r‘\.[\w\d]+$’, oldname)
-
if len(extension)>0:
-
extension = extension[0]
-
else: extension = ""
-
filename = instance.personalize_name(self.attname)
-
filename = self.upload_to + ‘_’.join(re.findall(r‘[a-zA-Z0-9]+’, filename)) + extension # leave only alphanum characters and add extension and add extension
-
try:
-
shutil.move(os.path.join(settings.MEDIA_ROOT, oldname), os.path.join(settings.MEDIA_ROOT, filename))
-
except IOError:
-
filename = oldname
-
setattr(instance, self.attname, filename)
-
-
def db_type(self):
-
"""Required by Django for ORM."""
-
return ‘varchar(100)’
And to your class definition you need to add something like this:
Python
-
class MyPhoto(models.Model):
-
photo = CustomImageField(upload_to="photos/")
-
owner = models.CharField(max_length=32)
-
uploaded = models.DateTimeField(auto_add_now=True)
-
-
def personalize_name(self, field_attname):
-
return "%s %s" % ( self.owner, self.uploaded ) # don’t worry about the non-alphanum characters
Assuming that the owner will be Bartosz Ptaszynski and the uploaded date 08-11-2007 13:06:00 and the file is photo.jpg the saved file will be:
photos/Bartosz_Ptaszynski_08_11_2007_13_06_00.jpg
Inspired by this blog. Thanks Scott.


Leave a Reply