Dea*_*dly 47 django django-models
我有UserProfile场模型avatar = models.ImageField(upload_to=upload_avatar)
upload_avatar函数名称图像文件根据user.id(例如12.png).
但是当用户更新头像时,新的头像名称与旧的头像名称一致,Django将后缀添加到文件名(例如12-1.png).
有办法覆盖文件而不是创建新文件?
Loc*_*jaw 62
是的,这也是我的想法.这就是我所做的.
模型:
from app.storage import OverwriteStorage
class Thing(models.Model):
image = models.ImageField(max_length=SOME_CONST, storage=OverwriteStorage(), upload_to=image_path)
Run Code Online (Sandbox Code Playgroud)
还在models.py中定义:
def image_path(instance, filename):
return os.path.join('some_dir', str(instance.some_identifier), 'filename.ext')
Run Code Online (Sandbox Code Playgroud)
在单独的文件中,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
Run Code Online (Sandbox Code Playgroud)
显然,这些是示例值,但总体而言,这对我来说效果很好,并且根据需要进行修改应该非常简单.
use*_*686 19
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
Run Code Online (Sandbox Code Playgroud)
Pyn*_*hia 12
嗯...这可能听起来不正统,但我目前的解决方案是检查并删除我已用于提供上传文件名称的回调中的现有文件.在models.py中:
import os
from django.conf import settings
def avatar_file_name(instance, filename):
imgname = 'whatever.xyz'
fullname = os.path.join(settings.MEDIA_ROOT, imgname)
if os.path.exists(fullname):
os.remove(fullname)
return imgname
class UserProfile(models.Model):
avatar = models.ImageField(upload_to=avatar_file_name,
default=IMGNOPIC, verbose_name='avatar')
Run Code Online (Sandbox Code Playgroud)
小智 10
您可以通过以下方式更好地编写存储类:
class OverwriteStorage(FileSystemStorage):
def get_available_name(self, name, max_length=None):
self.delete(name)
return name
Run Code Online (Sandbox Code Playgroud)
基本上,这将覆盖get_available_name删除文件的功能(如果已存在)并返回已存储的文件的名称
小智 8
对于 Django 1.10,我发现我必须修改最佳答案以在函数中包含 max_length 参数:
from django.core.files.storage import FileSystemStorage
import os
class OverwriteStorage(FileSystemStorage):
def get_available_name(self, name, max_length=None):
if self.exists(name):
os.remove(os.path.join(settings.MEDIA_ROOT, name))
return name
Run Code Online (Sandbox Code Playgroud)
您可以尝试定义自己的Filesystemstorage并覆盖默认的get_availbale_name方法.
from django.core.files.storage import FileSystemStorage
import os
class MyFileSystemStorage(FileSystemStorage):
def get_available_name(self, name):
if os.path.exists(self.path(name)):
os.remove(self.path(name))
return name
Run Code Online (Sandbox Code Playgroud)
对于您的图像,您可以定义这样的fs:
fs = MyFileSystemStorage(base_url='/your/url/',
location='/var/www/vhosts/domain/file/path/')
avatar = models.ImageField(upload_to=upload_avatar, storage=fs)
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
只需引用您的模型图像字段,将其删除并再次保存即可。
model.image.delete()
model.image.save()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25353 次 |
| 最近记录: |