How to prevent Django from changing file name when a file with that name already exists?
Asked Answered
G

3

8

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!

Glyceric answered 9/2, 2012 at 16:37 Comment(2)
Have a look here: #8332943Colfin
@Colfin the link is more to refer an existing file in the FS but the OP request here to overrides the file in the FS by a successive file provided in the FileField.Frangos
D
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)
Deirdredeism answered 9/2, 2012 at 17:47 Comment(3)
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.Glyceric
So you have to copy 50 lines of code, which is not really good. That's why it's better to override get_available_nameDeirdredeism
Refer to this question #15885701Fullfaced
Y
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):
Yolk answered 5/12, 2018 at 8:12 Comment(0)
S
0

Here is a solution when using the Models of Django and found it quite simple:

# create or get the current record (name and version get a unique record)
my_entity, created = MyEntityModel.objects.get_or_create(name=name, version=new_version) 

current_ts = timezone.now()
        
my_entity.description=description
my_entity.updated_at=current_ts
my_entity.updated_by=user_email

if created:
    # update the create meta in DB if new record
    my_entity.created_at=current_ts
    my_entity.created_by=user_email
else:
    # delete the existing file if not newly created
    # file is the FileField in MyEntityModel 
    my_entity.file.delete()

# here we create and save the file
content_file = ContentFile(file_content)
file_name = file_path
my_entity.file.save(file_name, content_file)

# and finally save the record                
my_entity.save()

I just delete the file if the record is already existing and in all case I save the content of the file.

Stalinism answered 3/6 at 22:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.