我正在开发一个小Django项目,我的models.py中有一个文件字段。 一切正常,但我不喜欢Django在上传后编辑文件名。它将空格更改为下划线,并删除(方形)括号和类似的东西。
有没有办法阻止Django这样做? 我可以看到,这是为了使网站更安全,更安全,也避免错误。但是,我是唯一一个能够上传文件的人。
希望有人知道这是否可能(以及如何):)
谢谢!
编辑:
这是models.py中的FileField:
file = models.FileField(upload_to=file_path)
这是我的upload_to:
def file_path(instance, filename):
extension = filename.split('.')[-1]
new_filename = '%s - %s.%s' % (str(instance.model.object_number), str(instance.model.object_name), str(extension))
return '/'.join(['files', str(instance.model.object_theme), str(instance.model.object_number), new_filename])
答案 0 :(得分:2)
是的,您可以编写自己的upload_to
函数,如文档中所述:https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.FileField.upload_to
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class MyModel(models.Model):
upload = models.FileField(upload_to=user_directory_path)
如果要避免覆盖具有相同名称的文件,则必须重新添加该功能。默认存储使用此功能django.core.file.storage.get_availble_name()
您可以阅读source code on github
编辑:看起来你的upload_to
函数没有返回任何内容。它应该将路径名作为字符串返回。
import os
def file_path(instance, filename):
base, extension = os.path.splitext(filename)
return '{model.object_number} - {model.object_name}{extension}'.format(
model=instance.model, extension=extension)
答案 1 :(得分:0)
您需要创建自己的存储类
import re
from django.utils.encoding import force_text
from django.utils.functional import keep_lazy_text
from django.core.files.storage import FileSystemStorage
@keep_lazy_text
def get_valid_filename(s):
"""
>>> get_valid_filename(" tawanda's portrait in 2019.jpg ")
'tawandas portrait in 2019.jpg'
"""
s = force_text(s).strip()
return re.sub(r'(?u)[^-\w. ]', '', s)
class CleanFileNameStorage(FileSystemStorage):
def get_valid_name(self, name):
"""
Return a filename, based on the provided filename, that's suitable for
use in the target storage system.
"""
return get_valid_filename(name)
如果您想将此存储应用于所有模型,则可以使用自定义类为Django设置DEFAULT_FILE_STORAGE
分配
DEFAULT_FILE_STORAGE = 'mystorage.CleanFileNameStorage'
如果这仅适用于特定型号,则:
def myfile_save_to(instance, filename):
return 'my_files/{filename}'.format(filename=filename)
class MyFileModel(models.Model):
my_file = models.FileField(
upload_to=myfile_save_to,
storage=CleanFileNameStorage(),
)
请记住,如果您在模型级别指定存储,则必须初始化类,例如CleanFileNameStorage()
如果不这样做,将会出现参数错误