How save filename of uploaded file in model

2019-09-07 05:22发布

问题:

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.

回答1:

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.