Question

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
Was it helpful?

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?

OTHER TIPS

If i understand correctly, if you rename a file , than the file gets duplicated instead of moved. Overriding the save method for Page class can get you access to the old and dew instance. http://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods

All you need to do is store the old filename in a variable, then after calling super.save() you can os.system("rm "+path_to_file) in the cases when the file changed. Does this help?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top