Django目录上传获取子目录名称 [英] Django directory upload get sub-directory names

查看:112
本文介绍了Django目录上传获取子目录名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在使用一个django应用程序来上传带有表单的文件目录。这是我使用的表单,允许上传目录:

  class FileFieldForm(forms.Form):
file_field = forms.FileField(widget = forms.ClearableFileInput(attrs =
{'multiple':True,'webkitdirectory':True,'directory':True}))

这是原始帖子有效载荷:

  ------ WebKitFormBoundaryPbO3HkrKGbBwgD3sd1 
Content-Disposition:form-data; name =csrfmiddlewaretoken

F575Bgl4U9dzgwePPeSW2ISZKk5c3CnRoqFasdasD0Hep6nD0LnAAObXbF92SUa96NbO2
------ WebKitFormBoundaryPbO3HkrKGbBwgDsd31
Content-Disposition:form-data; NAME = 是,file_field;
filename =MainDir / SubDir1 / 1.jpg
内容类型:image / jpeg


------ WebKitFormBoundaryPbOasd3HkrKGbBwgD31
内容-Disposition:表单数据; NAME = 是,file_field;
filename =MainDir / SubDir2 / 2.jpg
内容类型:image / jpeg

这是处理窗体的视图:

  class FileFieldView(FormView):
form_class = FileFieldForm
template_name ='upload.html'
success_url ='upload'

def post(self,request,* args,** kwargs):
form_class = self .get_form_class()
form = self.get_form(form_class)
files = request.FILES.getlist('file_field')
如果form.is_valid():
for f in文件:
pprint(文件名为+ f._get_name()+''+ f.field_name,sys.stderr)
new_file = FileModel(file = f)
new_file。 save()
return self.form_valid(form)
else:
return self.form_invalid(form)

问题是django中的文件对象的名称没有子目录名称。我假设中间件处理请求之一是从文件名解析和删除子目录名。有没有办法可以获得具有目录和子目录名称的原始文件名?

解决方案

我相信这是Django是如何实现。请参阅 Django的上传处理程序文档



它的默认上传处理程序 MemoryFileUploadHandler TemporaryFileUploadHandler 。他们都使用 UploadedFile 来处理这些文件,它有一个函数 _set_name ,它使用基本名称的文件。



即使有评论说为什么需要基本名称:

  def _set_name(self,name):
#清理文件名,使其不会危险。
如果名称不是None:
#只需使用文件的basename - 其他的都是危险的。
name = os.path.basename(name)

#超过255个字符的文件名可能会导致旧版本的操作系统出现问题。
如果len(name)> 255:
name,ext = os.path.splitext(name)
ext = ext [:255]
name = name [:255 - len(ext)] + ext

self._name = name

但我想你可以编写自己的上传处理程序这不需要您的基础名称和行为。以下是一些小信息,您可以如何编写自定义上传处理程序



然后,您需要在 FILE_UPLOAD_HANDLERS 设置中定义您的处理程序。


I am writing a django app to upload a directory of files with forms.

This is the form I am using which allows upload of directory:

class FileFieldForm(forms.Form):
    file_field = forms.FileField(widget=forms.ClearableFileInput(attrs=
        {'multiple': True, 'webkitdirectory': True, 'directory': True}))

This is the raw post payload:

------WebKitFormBoundaryPbO3HkrKGbBwgD3sd1
Content-Disposition: form-data; name="csrfmiddlewaretoken"

F575Bgl4U9dzgwePPeSW2ISZKk5c3CnRoqFasdasD0Hep6nD0LnAAObXbF92SUa96NbO2
------WebKitFormBoundaryPbO3HkrKGbBwgDsd31
Content-Disposition: form-data; name="file_field";
filename="MainDir/SubDir1/1.jpg"
Content-Type: image/jpeg


------WebKitFormBoundaryPbOasd3HkrKGbBwgD31
Content-Disposition: form-data; name="file_field";
filename="MainDir/SubDir2/2.jpg"
Content-Type: image/jpeg

This is the view to handle form:

class FileFieldView(FormView):
    form_class = FileFieldForm
    template_name = 'upload.html'
    success_url = 'upload'

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        files = request.FILES.getlist('file_field')
        if form.is_valid():
            for f in files:
                pprint("Name of file is " + f._get_name() + ' ' + f.field_name, sys.stderr)
                new_file = FileModel(file=f)
                new_file.save()
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

Problem is that name of file object in django is without sub-directory names. I am assuming one of the middleware handling request is parsing and removing subdirectory names from filename. Is there way I can get the original filename that has directory and sub-directory names?

解决方案

I believe this is how Django is implemented. Please refer to Django's Upload Handler doc.

It has its default upload handlers MemoryFileUploadHandler and TemporaryFileUploadHandler. Both of them are using the UploadedFile for handling the files, and it has a function _set_name, which takes the base name of the file.

Even there is a comment saying why it takes the basename:

def _set_name(self, name):
    # Sanitize the file name so that it can't be dangerous.
    if name is not None:
        # Just use the basename of the file -- anything else is dangerous.
        name = os.path.basename(name)

        # File names longer than 255 characters can cause problems on older OSes.
        if len(name) > 255:
            name, ext = os.path.splitext(name)
            ext = ext[:255]
            name = name[:255 - len(ext)] + ext

    self._name = name

But I think you can can write your own upload handler which doesn't take the basename and behaves as you want. Here is little info how you can write custom upload handler.

Then you need to define your handler in FILE_UPLOAD_HANDLERS setting.

这篇关于Django目录上传获取子目录名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆