从 Flask 中传递的不仅仅是结果页面 POST

Passing more than just the resultant page out of a Flask POST

(Flask 新手警报)

给定以下内容以在 Flask 中上传和保存文件:

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return render_template_string('''
                {% extends "base.html" %}
                {% block content %}
                <h4>File uploaded</h4>
                <p><a href={{ url_for('members_page') }}>Back</a></p>
                {% endblock %}
                ''')
        elif not allowed_file(file.filename):
            return render_template_string('''
            {% extends "base.html" %}
            {% block content %}
            <h3>Please try again</h3>
            <h4>File must be a .csv</h4>
            <p><a href={{ url_for('upload_file') }}>Back</a></p>
            {% endblock %}
            ''')
    return render_template_string('''
    {% extends "base.html" %}
    {% block content %}
    <h4>Upload CSV of Company/URL data</h2>
                <form action="" method="post" enctype="multipart/form-data">
                    <input type="file" name="file" />
                    <input type="submit" />
                </form>
    {% endblock %}
    ''')

我希望 filename 在另一个函数中可用:

@app.route('/scrape', methods=['GET', 'POST'])
@login_required                                 # Use of @login_required decorator
def scrape():
    parser = ConfigParser()
    parser.read('config.ini')
    keywords = parser.get('scrape', 'keywords').replace(' ', '').split(',')
    jobs = scraper.scrape(os.path.join(app.config['UPLOAD_FOLDER'], filename), keywords)

以上是 desired 意图,其中 filename 由 scrape 函数得知。显然,情况还不是这样。由于 upload_file() 在肯定情况下(确认页面)已经有一个 return 值,我怎样才能使 filename 可用? UPLOAD_FOLDER 将包含的不仅仅是上传的文件,所以我不能只将其中的任何内容加入此路径。

如果这是一个非 Flask 程序,我可能会 return locals() 然后访问适当的密钥,但我想如果我想维护确认页面。

您需要以某种方式连接两个请求。如果很多用户请求第一个,然后有人请求/scrape,你怎么知道哪个请求,他属于哪个文件名?

  1. 您可以使用会话(例如 cookie 会话,请参阅 http://pythonhosted.org/Flask-Session/)来跟踪上传的文件。将文件名存储在会话中,当同一用户(具有相同的 cookie)请求时 /scrape,您可以从用户会话中检索文件名。
  2. 您可以在第二个请求中包含要使用的文件名。这样,用户自己必须跟踪他上传的文件。

在任何一种情况下,尤其是在后者中,考虑文件的所有权很重要:哪个用户可以访问您系统上的哪个文件?

upload_file() 中选择文件名,在 scrape() 中取消选择。

PICKLED_CSV_FILENAME = 'pickled_csv_file_name'

def pickle_filename(filename, pickle_file):
    with open(os.path.join(UPLOAD_FOLDER, pickle_file),'wb') as p:
        pickle.dump(filename, p)

def load_pickled_filename(pickle_file):
    return pickle.load(open(os.path.join(UPLOAD_FOLDER, pickle_file), 'rb'))

upload_file()中:

pickle_filename(filename, PICKLED_CSV_FILENAME)

然后在 scrape():

jobs = scraper.scrape(os.path.join(app.config['UPLOAD_FOLDER'], load_pickled_filename(PICKLED_CSV_FILENAME)), keywords)

pickle_filename(文件名, PICKLED_CSV_FILENAME)

显然,对于许多 users/files 来说,这不是一个可持续的解决方案,但它是单个用户、单个文件的情况,因此它是可以接受的。