Django:如何阻止Django改变文件名(例如将空格转换为_)?

时间:2016-01-31 16:14:31

标签: python django

我正在开发一个小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])

2 个答案:

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

您需要创建自己的存储类

mystorage.py

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'

如果这仅适用于特定型号,则:

models.py

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()如果不这样做,将会出现参数错误