【问题标题】:Dropzone.js prevents Flask from rendering templateDropzone.js 阻止 Flask 渲染模板
【发布时间】:2017-06-25 09:38:36
【问题描述】:

我使用Dropzone.js 允许通过Flask 网站拖放上传CSV 文件。上传过程效果很好。我将上传的文件保存到我指定的文件夹,然后可以使用df.to_html()dataframe 转换为HTML 代码,然后将其传递给我的模板。它在代码中到达了这一点,但它不呈现模板并且不会引发任何错误。所以我的问题是为什么Dropzone.js 会阻止渲染发生?

我也试过只从表中返回HTML 代码而不使用render_template,但这也不起作用。

初始化.py

import os
from flask import Flask, render_template, request
import pandas as pd

app = Flask(__name__)

# get the current folder
APP_ROOT = os.path.dirname(os.path.abspath(__file__))

@app.route('/')
def index():
    return render_template('upload1.html')


@app.route('/upload', methods=['POST'])
def upload():

    # set the target save path
    target = os.path.join(APP_ROOT, 'uploads/')

    # loop over files since we allow multiple files
    for file in request.files.getlist("file"):

        # get the filename
        filename = file.filename

        # combine filename and path
        destination = "/".join([target, filename])

        # save the file
        file.save(destination)

        #upload the file
        df = pd.read_csv(destination)
        table += df.to_html()

    return render_template('complete.html', table=table)


if __name__ == '__main__':
    app.run(port=4555, debug=True)

上传1.html

<!DOCTYPE html>

<meta charset="utf-8">

<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script>
<link rel="stylesheet" href="https://rawgit.com/enyo/dropzone/master/dist/dropzone.css">


<table width="500">
    <tr>
        <td>
            <form action="{{ url_for('upload') }}", method="POST" class="dropzone"></form>
        </td>
    </tr>
</table>

编辑

这是我正在上传的示例csv 数据:

Person,Count
A,10
B,12
C,13

完成.html

<html>

<body>

{{table | safe }}

</body>
</html>

【问题讨论】:

  • complete.html 的内容是什么?
  • 实际上基本上只是通过render_template 传递的表格的html 代码。我已经添加了问题。

标签: javascript python python-2.7 flask dropzone.js


【解决方案1】:

如果您使用的是 Flask-Dropzone,那么:

{{ dropzone.config(redirect_url=url_for('endpoint',foo=bar)) }}

【讨论】:

  • 请完成您的问题以获得更好的答案
【解决方案2】:

更新:现在您可以使用Flask-Dropzone,这是一个将 Dropzone.js 与 Flask 集成的 Flask 扩展。对于此问题,您可以将DROPZONE_REDIRECT_VIEW 设置为上传完成时要重定向的视图。


Dropzone.js 使用 AJAX 发布数据,这就是它不会将控制权交还给您的视图功能的原因。

当所有文件上传完成后,有两种方法可以重定向(或渲染模板)。

  • 您可以添加一个按钮来重定向。

    &lt;a href="{{ url_for('upload') }}"&gt;Upload Complete&lt;/a&gt;

  • 您可以将事件监听器添加到自动重定向页面(使用 jQuery)。

    <script>
    Dropzone.autoDiscover = false;
    
    $(function() {
      var myDropzone = new Dropzone("#my-dropzone");
      myDropzone.on("queuecomplete", function(file) {
        // Called when all files in the queue finish uploading.
        window.location = "{{ url_for('upload') }}";
      });
    })
    </script>
    

在视图函数中,添加if语句,检查HTTP方法是否为POST

import os
from flask import Flask, render_template, request

app = Flask(__name__)
app.config['UPLOADED_PATH'] = 'the/path/to/upload'

@app.route('/')
def index():
    # render upload page
    return render_template('index.html')


@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        for f in request.files.getlist('file'):
            f.save(os.path.join('the/path/to/upload', f.filename))
    return render_template('your template to render')

【讨论】:

    【解决方案3】:

    您的代码确实有效。您的模板将被渲染并返回。

    Dropzone 会将您拖放到浏览器中的文件“在后台”上传。 它将消耗来自服务器的响应并保持页面不变。它使用来自服务器的响应来判断上传是否成功。

    查看实际效果:

    • 导航到您的页面
    • 打开你喜欢的浏览器开发工具; (在 Firefox 中按 CTRL+SHIFT+K)
    • 选择网络标签
    • 将您的 csv 拖到 dropzone 窗格中,并注意请求显示在开发工具网络表中

    这是我浏览器的屏幕截图。我按照您的问题复制了您的代码。

    要真正看到呈现的complete.html,您需要添加另一个烧瓶端点并有一种导航到该端点的方法。

    例如: 在upload1.html 添加:

    <a href="{{ url_for('upload_complete') }}">Click here when you have finished uploading</a>
    

    init.py 中更改并添加:

    def upload():
    
        ...
    
            # you do not need to read_csv in upload()
            #upload the file
            #df = pd.read_csv(destination)
            #table += df.to_html()
    
        return "OK"
        # simply returning HTTP 200 is enough for dropzone to treat it as successful
        # return render_template('complete.html', table=table)
    
    # add the new upload_complete endpoint
    # this is for example only, it is not suitable for production use
    @app.route('/upload-complete')
    def upload_complete():
        target = os.path.join(APP_ROOT, 'uploads/')
        table=""
        for file_name in os.listdir(target):
            df = pd.read_csv(file_name)
            table += df.to_html()
        return render_template('complete.html', table=table)
    

    【讨论】:

    • 谢谢,很好的回答。我确实最终添加了一个链接。没办法自动渲染?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2012-06-12
    相关资源
    最近更新 更多