【问题标题】:Folder picker in HTML with Flask for Uploads带有 Flask for Uploads 的 HTML 中的文件夹选择器
【发布时间】:2016-12-26 20:29:12
【问题描述】:

我正在运行一个 Flask 应用程序,用户在其中上传文件,并且必须选择在网络驱动器上上传文件的根文件夹路径。此路径是 IIS 可用的网络路径,也是所有用户计算机上的网络驱动器。

我想在 HTML 中动态显示可用文件夹,即使在应用启动后创建了新文件夹。

我知道由于安全原因,纯 HTML 无法做到这一点,但我想知道 Flask 是否有办法解决这个问题。目标是使用 Python 将上传文件移动到选择的文件夹路径。

我试过了:

<form><input type="file" name=dir webkitdirectory directory multiple/></form>

但这仅适用于 Chrome。使用用户选择的路径,我可以将其传递给 Python 以将上传文件复制到那里。

【问题讨论】:

    标签: python html flask


    【解决方案1】:

    由于现代浏览器的限制,我决定使用 JSTree 作为解决方案。它运行良好。它具有树结构浏览器。该结构是将文件夹输出为 JSON 的结果。您也可以添加搜索栏,以便用户只需输入文件夹名称即可搜索。
    请看JSTree https://www.jstree.com/

    如何用 Flask 实现这一点

    HTML/JS:

      <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css">
      <div>
      <input class="search-input form-control" placeholder="Search for folder"></input>
      </div>
    <script id="jstree1" name="jstree1">
                            /*Search and JS Folder Tree*/
                            $(function () {
                                $(".search-input").keyup(function () {
                                    var searchString = $(this).val();
                                    console.log(searchString);
                                    $('#container').jstree('search', searchString);
                                });
                                $('#container').jstree({
                                    'core': {
                                        "themes": {
                                            "name": "default"
                                            , "dots": true
                                            , "icons": true
                                        }
                                        , 'data': {
                                            'url': "static/JSONData.json"
                                            , 'type': 'GET'
                                            , 'dataType': 'JSON'
                                        }
                                    }
                                    , "search": {
                                        "case_insensitive": true
                                        , "show_only_matches": true
                                    }
                                    , "plugins": ["search"]
                                });
                            });
    
                            { /*  --- THIS IS FOLDER SELECTOR FOR ID "folderout" --- */
                                $("#container").on("select_node.jstree", function (evt, data) {
                                    var number = data.node.text
    
                                    document.getElementById("folderout").value = number;
                                });
    

    在 Flask/WTForms 中调用 id "folderout"。当用户单击文件夹时,这将返回 WTForms 的路径。

    folderout = TextField('Folder:', validators=[validators.required()])
    

    使用 Python 创建 JSON JStree 文件:

    import os
    
    # path   : string to relative or absolute path to be queried
    # subdirs: tuple or list containing all names of subfolders that need to be
    #          present in the directory
    def all_dirs_with_subdirs(path, subdirs):
        # make sure no relative paths are returned, can be omitted
        path = os.path.abspath(path)
    
        result = []
        for root, dirs, files in os.walk(path):
            if all(subdir in dirs for subdir in subdirs):
                    result.append(root)
        return result
    
    def get_directory_listing(path):
        output = {}
        output["text"] = path.decode('latin1')
        output["type"] = "directory"
        output["children"] = all_dirs_with_subdirs(path, ('Maps', 'Reports'))
        return output
    
    with open('test.json', 'w+') as f:
        listing = get_directory_listing(".")
        json.dump(listing, f)
    

    【讨论】:

      【解决方案2】:

      Python 在您的服务器上运行,因此无法使用它在客户端移动文件。如果你考虑一下,假设你设法以某种方式(神奇地)向客户端发送 python 命令来移动文件,你知道他们是否甚至安装了 python 来解释你的命令吗?

      另一方面,

      Javascript 在客户端运行并用于实现此目的。但是,就像您说的那样,由于安全原因,现代浏览器不允许这样做。如果他们允许,那么任何网站都可能看到您的整个文件系统。

      这是一个article,它解释了一些原因。查找它的文件上传控制部分。希望这能让事情更清楚一些。

      编辑:看到您的评论后,您可以使用 os.walk 实现。请注意它可能会很慢。

      for root, dirs, files in os.walk(rootPath): # for example "C:/Users/"
          for file in files:
              if file == (wantedFile):
                  print(os.path.join(root,file))
                  break
      

      【讨论】:

      • 感谢limbo的帮助。但是我希望用户在服务器端移动文件时选择路径。服务器与客户端对网络文件夹具有相同的访问权限,因此这不是问题。事实上,如果允许用户从服务器端查看文件夹路径,这也将完成我想要做的事情。
      • hmm,你可以使用 os.walk 来查找文件。我会编辑我的答案
      • 感谢这将有助于列出文件夹。现在我只需要弄清楚如何为各种文件夹路径创建一个类似列表和 SelectField 的下拉列表。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      • 1970-01-01
      • 2013-04-12
      相关资源
      最近更新 更多