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
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
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
from django.db.models.signals import pre_save
@receiver(pre_save, sender=Attachment)
def attachment_file_update(sender, **kwargs):
attachment = kwargs['instance']
# As it was not yet saved, we get the instance from DB with
# the old file name to delete it. Which won't happen if it's a new instance
if attachment.id:
attachment = Attachment.objects.get(pk=attachment.id)
storage, path = attachment.its_file.storage, attachment.its_file.path
storage.delete(path)
9条答案
按热度按时间9rbhqvlz1#
是啊,我也想到了。我是这么做的。
型号:
也在www.example中定义 www.example.com
在单独的文件www.example中 www.example.com
显然,这里的值是示例值,但总的来说,这对我来说很好,而且在必要时修改应该很简单。
rdlzhqv92#
ukxgm1gy3#
你可以用这种方式更好地编写存储类:
基本上,这将覆盖函数
get_available_name
以删除文件(如果文件已存在)并返回已存储文件的名称41ik7eoe4#
只需引用您的模型图像字段,删除它并再次保存。
oewdyzsn5#
嗯……这听起来可能不太正统,但我的解决方案,目前,是检查并删除回调中的现有文件,我已经使用它来提供上传文件的名称。Inwww.example. www.example.com
tez616oj6#
对于Django 1.10我发现我必须修改最上面的答案,以便在函数中包含max_length参数:
csga3l587#
您可以尝试定义自己的Filesystemstorage并覆盖默认的get_availbale_name方法。
对于你的镜像,你可以像这样定义一个fs:
希望这能帮上忙。
sqyvllje8#
我尝试了这里提到的解决方案。但它似乎在Django 1上不起作用。10.它会在管理员模板的某个地方引发以下错误:
url() missing 1 required positional argument: 'name'
所以我想出了自己的解决方案,它包括创建一个pre_保存信号,试图在保存之前从数据库中获取示例并删除它的文件路径:
mm5n2pyu9#
在Django 4.2您可以尝试定义自己的Filesystemstorage并覆盖默认的exists方法。
并使用新的文件系统类定义模型