7

In my case I allow user to upload an avatar picture and use user_id as filename, simply. So there will be 1.jpg, 2.jpg, etc.

However I found if I upload a new avatar for some account that already has one uploaded, let's say user #10, the new file will be named as "10_1.jpg". This is OKay, however I don't need it and I hope new file could overwrite the old one - it also saves some disk space anyway.

I googled and searched but couldn't find a clue. I was hoping there would be an option for ImageField or FileField but it's not there.

Thanks for help!

x1a0
  • 9,984
  • 5
  • 22
  • 30
  • Have a look here: http://stackoverflow.com/questions/8332443/set-djangos-filefield-to-an-existing-file – Jingo Feb 09 '12 at 17:39

2 Answers2

14

You should define your own storage, inherit it from FileSystemStorage, and override get_available_name function in it. The use this storage for your imagefield. Something like this:

class OverwriteStorage(FileSystemStorage):

    def get_available_name(self, name):
        if self.exists(name):
            os.remove(os.path.join(SOME_PATH, name))
        return name

fs = OverwriteStorage(location=SOME_PATH)

class YourModel(models.Model):
    image_file = models.ImageField(storage=fs)
Michael Gendin
  • 3,285
  • 2
  • 18
  • 23
  • Hey man. I just found this is the right place to begin with however `get_available_name` is not the method to override. I override `_save` and everything works now. – x1a0 Mar 23 '12 at 12:49
  • So you have to copy 50 lines of code, which is not really good. That's why it's better to override get_available_name – Michael Gendin Mar 29 '12 at 20:47
  • Refer to this question http://stackoverflow.com/questions/15885201/django-uploads-discard-uploaded-duplicates-use-existing-file-md5-based-check?answertab=votes#tab-top – jdcaballerov Feb 04 '14 at 18:01
2

Michael Gendin's solution above works great for Django 2.1 (Hello from 2018!). It is only necessary to add the "max_length" attribute to the "get_available_name" method:

def get_available_name(self, name, max_length=None):