Django FileField阻止双字节文件名自动编码问题求助
Django FileField 中文文件名被编码问题
我的Django模型中使用了FileField,代码如下:
class Drawing(models.Model): drawing = models.FileField(upload_to='uploads/')
上传如「木.pdf」这类含双字节字符的文件名时,文件名会被自动编码为「%E6%9C%A8_sBMogAs.pdf」。我尝试重写FileField的代码,从Django官方仓库复制代码后添加打印语句追踪文件名变化,在pre_save、generate_filename、save_form_data、save方法中检查,发现这些节点的文件名仍为「木.pdf」或「木_sBMogAs.pdf」,并未出现编码后的名称。
请问文件名是在哪个环节被编码的?如何避免该编码操作?
编码环节定位
这个编码操作发生在**存储后端(Storage)**的get_valid_name或save方法里,默认的FileSystemStorage会对文件名进行urlencode处理,而FileField本身的方法并不会做这个操作,所以你在FileField的方法里追踪不到编码过程。
解决方法
要保留双字节字符文件名,你可以自定义存储后端,重写get_valid_name方法,跳过urlencode步骤:
- 在项目中创建一个自定义存储类,比如
storages.py:
from django.core.files.storage import FileSystemStorage class UnicodeFileSystemStorage(FileSystemStorage): def get_valid_name(self, name): # 直接返回原文件名,不做urlencode处理 return name
- 在FileField中指定使用这个自定义存储:
from .storages import UnicodeFileSystemStorage class Drawing(models.Model): drawing = models.FileField(upload_to='uploads/', storage=UnicodeFileSystemStorage())
注意:如果你的存储后端是其他类型(比如云存储),需要对应修改该后端的文件名处理逻辑。另外,确保你的服务器文件系统支持双字节字符编码(比如UTF-8),避免出现文件存储或读取异常。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

