Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImageField overwrite image file with same name

I have model UserProfile with field avatar = models.ImageField(upload_to=upload_avatar)

upload_avatar function names image file according user.id (12.png for example).

But when user updates the avatar, new avatar name coincide with old avatar name and Django adds suffix to file name (12-1.png for example).

There are way to overwrite file instead of create new file?

like image 205
Deadly Avatar asked Mar 01 '12 19:03

Deadly


2 Answers

Yeah, this has come up for me, too. Here's what I've done.

Model:

from app.storage import OverwriteStorage  class Thing(models.Model):     image = models.ImageField(max_length=SOME_CONST, storage=OverwriteStorage(), upload_to=image_path) 

Also defined in models.py:

def image_path(instance, filename):     return os.path.join('some_dir', str(instance.some_identifier), 'filename.ext') 

In a separate file, storage.py:

from django.core.files.storage import FileSystemStorage from django.conf import settings import os  class OverwriteStorage(FileSystemStorage):      def get_available_name(self, name):         """Returns a filename that's free on the target storage system, and         available for new content to be written to.          Found at http://djangosnippets.org/snippets/976/          This file storage solves overwrite on upload problem. Another         proposed solution was to override the save method on the model         like so (from https://code.djangoproject.com/ticket/11663):          def save(self, *args, **kwargs):             try:                 this = MyModelName.objects.get(id=self.id)                 if this.MyImageFieldName != self.MyImageFieldName:                     this.MyImageFieldName.delete()             except: pass             super(MyModelName, self).save(*args, **kwargs)         """         # If the filename already exists, remove it as if it was a true file system         if self.exists(name):             os.remove(os.path.join(settings.MEDIA_ROOT, name))         return name 

Obviously, these are sample values here, but overall this works well for me and this should be pretty straightforward to modify as necessary.

like image 98
Lockjaw Avatar answered Sep 19 '22 02:09

Lockjaw


class OverwriteStorage(get_storage_class()):      def _save(self, name, content):         self.delete(name)         return super(OverwriteStorage, self)._save(name, content)      def get_available_name(self, name):         return name 
like image 21
user2732686 Avatar answered Sep 23 '22 02:09

user2732686