通过管理界面上传图像的自定义文件名

时间:2012-01-27 10:03:53

标签: django django-admin

我有一个带有ImageField()字段的Django模型。现在我想在保存到文件系统之前重命名图像的文件名(基于同一型号的唯一CharField)。此外,如果已存在具有相同文件名的图像,则应重命名现有文件,并且新上载的文件应保留其文件名。

我不太确定这是正确的或首选的方法。我应该覆盖ModelAdmin.save_model(),在Model.save()方法中执行此操作还是编写自己的自定义文件存储空间?

任何人都可以给我一些打击,我怎么能做到这一点?任何提示或示例代码都非常感谢。

3 个答案:

答案 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

http://lightbird.net/dbe/photo.html