2016-11-17 69 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