我有一个带有ImageField()
字段的Django模型。现在我想在保存到文件系统之前重命名图像的文件名(基于同一型号的唯一CharField)。此外,如果已存在具有相同文件名的图像,则应重命名现有文件,并且新上载的文件应保留其文件名。
我不太确定这是正确的或首选的方法。我应该覆盖ModelAdmin.save_model(),在Model.save()方法中执行此操作还是编写自己的自定义文件存储空间?
任何人都可以给我一些打击,我怎么能做到这一点?任何提示或示例代码都非常感谢。
答案 0 :(得分:1)
您可以在此处组合两种机制:在字段定义中传递upload_to
参数和自定义FileSystemStorage
后端。
这是一个带有upload_to可调用的虚拟模型:
def upload_bar(instance, filename):
# Do something with the filename
return new_filename
class Foo(models.Model):
bar = models.ImageField(upload_to=upload_bar)
...
自定义虚拟FileSystemStorage后端:
from django.core.files.storage import FileSystemStorage
class OverwriteStorage(FileSystemStorage):
def _save(self, name, content):
if self.exists(name):
# Rename it
return super(OverwriteStorage, self)._save(name, content)
def get_available_name(self, name):
return name
但是,我会非常谨慎地干预现有文件(即更改现有文件的名称)。请注意,即使删除了对象,Django也不会从文件系统中删除该文件。
答案 1 :(得分:0)
以下是获取18f6ad9f-5cec-4420-abfd-278bed78ee4a.png
models.py
import os
import uuid
from django.conf import settings
from django.db import models
def make_upload_path(instance, filename):
file_root, file_ext = os.path.splitext(filename)
dir_name = '{module}/{model}'.format(module=instance._meta.app_label, model=instance._meta.module_name)
file_root = unicode(uuid.uuid4())
name = os.path.join(settings.MEDIA_ROOT, dir_name, file_root + file_ext.lower())
# Delete existing file to overwrite it later
if instance.pk:
while os.path.exists(name):
os.remove(name)
return os.path.join(dir_name, file_root + file_ext.lower())
class YourModel(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(blank=True, upload_to=make_upload_path)
答案 2 :(得分:-1)
您可以从Model.save()
访问self.image.name