Tuesday, April 10, 2012

How save filename of uploaded file in model

I need save without full path to file also filename.
I doing so:


class Photo(models.Model):
     photo = models.ImageField(upload_to = settings.PATH_PHOTOS_SOURCE)
     user = models.ForeignKey(UserProfile, editable=False)
     item = models.ForeignKey(Item, default=0)
     filename = models.CharField(max_length=100, default='', editable=False)
 
     def save(self, *args, **kwargs):
         self.filename = os.path.basename(self.photo.url)
         super(Photo, self).save(*args, **kwargs)
 


It's work, but exist cases, when file with existing name already exist, and offcourse in disk write file example_1.jpg, example_2.jpg, but in filename saving incorrect filename example.jpg


I changed my save method so:


def save(self, *args, **kwargs):
     super(Photo, self).save(*args, **kwargs)        
     self.filename = os.path.basename(self.photo.url)
     super(Photo, self).save()
 


It's work, but i don't like this code, maybe is more elegant code.


I tried to do this with signals, but i had problem with save recursion.



Answer:

Instead of settings.PATH_PHOTOS_SOURCE, pass a function to upload_to.
def upload_path_handler(self, filename):
    return os.path.join(settings.PATH_PHOTOS_SOURCE,
                        os.path.basename(self.photo.url))
# in model
photo = models.ImageField(upload_to=upload_path_handler)
If you want to use model instance id for filename, ref Django admin file upload with current model id
You may need to consider possible value of photo.url to make sure its safe to directly use it as filename.

No comments:

Post a Comment