Search code examples
djangodjango-modelsdjango-file-upload

django ImageField - how to customise name + remove old file


I have a model with an ImageField in it. I've already set the upload_to and created my own FileSystemStorage class to deal with saving the file with a unique name... however...

This setup allows me to upload and save a file with a unique name for each file (which is fine), but I also need it to remove the previous file that existed, e.g.

I upload file1.png and it's saved as file1_xkdeujg.png (that's just a random string)

I then go into django admin (using the django admin interface so need to do via the model) and change the image for that field to fileNEW.png

What needs to happen now is:

1) it saves the new file as fileNEW_fjewiejk.png (unique random string each time image saved) - done

2) it saves the new file into the database - done

3) it removes the old file - file1_xkdeuig.png - from the filesystem - not done

Q: Can anyone help me with point 3?

Some code:

class Page(models.Model):
    image           = models.ImageField(upload_to='pages/', storage=MyFileSystemStorage())

And (borrowed the bulk of this code from somewhere else...):

class MyFileSystemStorage(FileSystemStorage):

    def get_valid_name(self, name):
            file_root, file_ext = os.path.splitext(name)
            return "%s_%s%s" % (file_root, rand_key(8), file_ext)

    def get_available_name(self, name):
            dir_name, file_name = os.path.split(name)
            file_root, file_ext = os.path.splitext(file_name)
            count = itertools.count(1)
            while self.exists(name):
                    name = os.path.join(dir_name, "%s_%s%s" % (rand_key(32),  count.next(), file_ext))
            return name

Solution

  • The answer came from a similar question on StackOverflow...

    Basically, you store the original image in the init method, and then check to see if it has changed prior to the save.

    After the save, delete the image stored at the original image path.

    See this answer too (Josh's answer is the one I used and prefer as it doesn't hit the database).

    Django: When saving, how can you check if a field has changed?