ImageField 覆盖同名的图像文件 [英] ImageField overwrite image file with same name

查看:20
本文介绍了ImageField 覆盖同名的图像文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有模型 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆