ImageField 覆盖同名的图像文件 [英] ImageField overwrite image file with same name
问题描述
我有模型 UserProfile
字段 avatar = models.ImageField(upload_to=upload_avatar)
upload_avatar
函数根据 user.id
命名图像文件(例如 12.png).
upload_avatar
function names image file according user.id
(12.png for example).
但是当用户更新头像时,新的头像名称与旧的头像名称重合,并且Django在文件名后添加了后缀(例如12-1.png).
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).
有没有办法覆盖文件而不是创建新文件?
推荐答案
是的,我也遇到了这个问题.这就是我所做的.
Yeah, this has come up for me, too. Here's what I've done.
型号:
from app.storage import OverwriteStorage
class Thing(models.Model):
image = models.ImageField(max_length=SOME_CONST, storage=OverwriteStorage(), upload_to=image_path)
也在models.py中定义:
Also defined in models.py:
def image_path(instance, filename):
return os.path.join('some_dir', str(instance.some_identifier), 'filename.ext')
在一个单独的文件中,storage.py:
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.
这篇关于ImageField 覆盖同名的图像文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!