2012-01-27 35 views
0

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

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

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

回答

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也不会从文件系统中删除文件。

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) 
相关问题