2016-11-17 67 views
7

我正在写一个django应用程序来上传带有表单的文件目录。Django目录上传获取子目录名称

这是我使用的形式,它允许目录上传:

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

这是原始POST负载:

------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 

这是处理表单视图:

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) 

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

回答

3

我相信这是如何实现Django。请参考Django's Upload Handler doc

它有它的默认上传处理程序MemoryFileUploadHandlerTemporaryFileUploadHandler。他们都使用UploadedFile来处理文件,并且它有一个功能_set_name,它取得文件的基本名称。

甚至有评论说,为什么它需要的基本部分:

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 

但我认为你可以可以写不拿基名,当你想表现自己的上传处理程序。这里有一点你可以写custom upload handler

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

+1

谢谢为了更好的格式化@Moinuddin Quadri –

+1

我错过了文档。我会试试这个,它应该工作。 – pratsJ

0

扩大在以前的答案,从目录上传获取完整路径的一种方式是通过在文件路径替换斜杠(\/)用连字符(其中获得消毒远):

class CustomMemoryFileUploadHandler(MemoryFileUploadHandler): 
    def new_file(self, *args, **kwargs): 
     args = (args[0], args[1].replace('/', '-').replace('\\', '-')) + args[2:] 
     super(CustomMemoryFileUploadHandler, self).new_file(*args, **kwargs) 

class CustomTemporaryFileUploadHandler(TemporaryFileUploadHandler): 
    def new_file(self, *args, **kwargs): 
     args = (args[0], args[1].replace('/', '-').replace('\\', '-')) + args[2:] 
     super(CustomTemporaryFileUploadHandler, self).new_file(*args, **kwargs) 

@csrf_exempt 
def my_view(request): 
    # replace upload handlers. This depends on FILE_UPLOAD_HANDLERS setting. Below code handles the default in Django 1.10 
    request.upload_handlers = [CustomMemoryFileUploadHandler(request), CustomTemporaryFileUploadHandler(request)] 
    return _my_view(request) 

@csrf_protect 
def _my_view(request): 
    # if the path of the uploaded file was "test/abc.jpg", here it will be "test-abc.jpg" 
    blah = request.FILES[0].name