将以前上传的文件列表返回烧瓶

时间:2018-03-20 13:08:51

标签: python flask

我正在尝试通过扩展this教程制作一个简单的数据比较工具(使用kolmogorov-smirnov)来学习Flask,因为我正在考虑“记住”#39;应该提供给执行kolmogorov-smirnov测试的函数的上传文件列表。

我已经尝试了几个选项,但是到目前为止还无法将以前选择和上传的文件列表显示在我的虚拟模板(foo.html)中。因此,问题是我的想法(将变量交给模板,并从模板中取回)是一个坏主意,如果是这样的话,应该如何做?

test.py

import os
from flask import Flask, render_template, request, redirect, url_for, send_from_directory
from werkzeug import secure_filename

# Initialize the Flask application
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = './uploads/'
app.config['ALLOWED_EXTENSIONS'] = set(['txt','arw'])

def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']

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

@app.route('/upload', methods=['POST'])
def upload():
    uploaded_files = request.files.getlist("file[]")
    filenames = []
    for file in uploaded_files:
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'],filename))
            filenames.append(filename)
    return render_template('upload.html', filenames=filenames)

@app.route('/ks_test', methods=['POST'])
def ks_test(filenames):
    return render_template('foo.html', content=filenames)

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

的index.html

<!DOCTYPE html>
<html lang="en">
 <head>
  <link href="bootstrap/3.0.0/css/bootstrap.min.css"
  rel="stylesheet">
 </head>
 <body>
  <div class="container">
   <div class="header">
    <h3 class="text-muted">How To Upload a File.</h3>
   </div>
   <hr/>
   <div>
   <form action="upload" method="post" enctype="multipart/form-data">
   <input type="file" multiple="" name="file[]" class="span3" /><br/>
    <input type="submit" value="Upload" class="span2">
   </form>
   </div>
  </div>
 </body>
</html>

upload.html

<!DOCTYPE html>
<html lang="en">
 <head>
  <link href="bootstrap/3.0.0/css/bootstrap.min.css"
     rel="stylesheet">
 </head>
 <body>
  <div class="container">
   <div class="header">
    <h3 class="text-muted">Uploaded files</h3>
   </div>
   <hr/>
   <div>
   This is a list of the files you just uploaded, click on them to load/download them
   <ul>
    {% for file in filenames %}
     <li>{{file}}</li>
    {% endfor %}
   </ul>
   <hr/>
   <!-- How to return the filenames list back to the python part? -->
   <form action="ks_test" method="post">
     <input type="hidden" name="files" value={{ filenames }}>
     <input type="submit" value="Kolmogorov-Smirnov test">  
   </form>
   </div>
  </div>
 </body>
</html>

foo.html

<!DOCTYPE html>
<html lang="en">
 <head>
  <link href="bootstrap/3.0.0/css/bootstrap.min.css"
  rel="stylesheet">
 </head>
 <body>
  <div>
    <pre>{{ content }}</pre>
  </div>
 </body>
</html>

上面代码段给出的错误是TypeError,因为我还没弄清楚如何返回一个变量,因此函数期望一个它从未收到的输入变量。

TypeError: ks_test() takes exactly 1 argument (0 given) 

更新1

我已经进一步了解了一个状态,我可以通过使用以下更改的函数从上传文件列表中检索1项:

test.py

@app.route('/ks_test', methods=['POST','GET'])
def ks_test():
    filenames = request.form.getlist('filenames')
    return render_template('foo.html', content=filenames)

upload.html

   <form action="ks_test" method="post">
     <input type="hidden" name="filenames" value={{ filenames }}>
     <input type="submit" value="Kolmogorov-Smirnov test">  
   </form>

foo.html

<!DOCTYPE html>
<html lang="en">
 <head>
  <link href="bootstrap/3.0.0/css/bootstrap.min.css"
  rel="stylesheet">
 </head>
 <body>
  <div>
    <ul>
    {% for i in content %}
      <li>{{ i }}</li>
    {% endfor %}
    </ul>
  </div>
 </body>
</html>

但是,如果上传了一个文件,这只会检索{{ filenames }}的1个元素,如以下输出所示。

  • [&#39; d-00342-血清D7_Emission_1.txt&#39;]

如果上传了多个项目,则会产生以下输出:

  • [&#39; d-00342-血清D6_Emission_1.txt&#39;,

请注意列表未清楚的明确指示。

1 个答案:

答案 0 :(得分:0)

短篇小说...不要尝试这样做,请使用session,如下所述。但是,如果有更正确/更好的方法,请告诉我。

test.py

import os
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, session
from werkzeug import secure_filename

# Initialize the Flask application
app = Flask(__name__)
app.secret_key = 'xyz'
app.config['UPLOAD_FOLDER'] = './uploads/'
app.config['ALLOWED_EXTENSIONS'] = set(['txt','arw'])

def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']

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

@app.route('/upload', methods=['POST'])
def upload():
    uploaded_files = request.files.getlist("file[]")
    filenames = []
    for file in uploaded_files:
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'],filename))
            filenames.append(filename)
    # This line is essential, store the data in session
    session['filenames'] = filenames
    return render_template('upload.html', filenames=filenames)

@app.route('/ks_test')
def ks_test():
    return render_template('foo.html', content=session['filenames'])

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

upload.html

<!DOCTYPE html>
<html lang="en">
 <head>
  <link href="bootstrap/3.0.0/css/bootstrap.min.css"
     rel="stylesheet">
 </head>
 <body>
  <div class="container">
   <div class="header">
    <h3 class="text-muted">Uploaded files</h3>
   </div>
   <hr/>
   <div>
   This is a list of the files you just uploaded, click on them to load/download them
   <ul>
    {% for file in filenames %}
     <li><a href="{{url_for('uploaded_file', filename=file)}}">{{file}}</a></li>
    {% endfor %}
   </ul>
   <hr/>
   <form action="ks_test">
     <input type="submit" value="Kolmogorov-Smirnov test">  
   </form>
   </div>
  </div>
 </body>
</html>

foo.html

<!DOCTYPE html>
<html lang="en">
 <head>
  <link href="bootstrap/3.0.0/css/bootstrap.min.css"
  rel="stylesheet">
 </head>
 <body>
  <div>
    <ul>
    {% for i in content %}
      <li>{{ i }}</li>
    {% endfor %}
    </ul>
  </div>
 </body>
</html>

如果选择了两个文件,则会产生以下输出:

* D-00342-serum-D6_Emission_1.txt
* D-00342-serum-D7_Emission_1.txt