热门标签:
Q:

使用Flask上传和下载文件

我试图用PythonAnywhere和Flask编写一个非常简单的webapp,它允许用户上传文本文件,生成csv文件,然后让用户下载csv文件。 它不必是花哨的,它只需要工作。 我已经编写了从驱动器上的txt文件生成csv的程序。

现在,我的函数打开驱动器上的文件:

with open(INPUTFILE, "r") as fname:

并将csv写入:

with open(OUTPUTFILE, 'w') as fname:

输入文件和输出文件是文件名字符串。

我以某种方式将文件作为对象处理,由flask/html返回会更好吗?

我不知道该怎么做。 我应该如何构建这个程序? 我需要多少HTML模板? 我更愿意处理文件wihthout将它们保存在任何地方,但如果我必须将它们保存到PythonAnywhere目录,我可以。 我该怎么做?

原网址
A:

PythonAnywhere在这里。 这是关于Flask和web开发的一个很好的问题,而不是特定于我们的系统,所以我会尝试给出一个通用的答案,而没有任何特定于我们:-)

有几件事我需要知道才能对你的问题给出一个明确的答案,所以我将首先列出我所做的假设-如果我对其中任何一个错误请留下评论,我会适当地更新答案。

  • 我假设你上传的文件不是很大,可以容纳一个合理的内存量--比如说,小于一兆字节。
  • 我假设您已经编写的从文本文件生成CSV的程序是在Python中,并且它具有(或者更可能的是,可以很容易地更改为具有)一个函数,该函数接受包含文本文件内容的字符串,并返回需要写入CSV的内容。

如果两者都是这种情况,那么构建Flask应用程序的最佳方法是处理Flask内的所有内容。 一个代码示例胜过千言万语,所以这里有一个简单的示例,它允许用户上传一个文本文件,通过一个名为 transform 的函数运行它(这是转换程序中的函数将 这里有一个在PythonAnywhere上的这个应用程序的实时版本

from flask import Flask, make_response, request

app = Flask(__name__)

def transform(text_file_contents):
    return text_file_contents.replace("=", ",")


@app.route('/')
def form():
    return """
        
            
                

Transform a file demo

""" @app.route('/transform', methods=["POST"]) def transform_view(): request_file = request.files['data_file'] if not request_file: return "No file" file_contents = request_file.stream.read().decode("utf-8") result = transform(file_contents) response = make_response(result) response.headers["Content-Disposition"] = "attachment; filename=result.csv" return response

关于你的其他问题:

  • 模板:我没有在这个例子中使用模板,因为我希望所有的模板都适合一段代码。 如果我做得正确,那么我会把由 form 视图生成的东西放到一个模板中,但仅此而已。
  • 你可以通过写入文件来做到这一点-是的,你可以,上传的文件可以通过使用 save( filename ) 方法保存在我使用 stream 属性的 file 对象上。 但是如果你的文件很小(根据我上面的假设),那么像上面的代码一样在内存中处理它们可能更有意义。

我希望所有的帮助,如果你有任何问题,然后发表评论。

所有回答

共 1 条

author avatar

更好地添加

response.headers["Cache-Control"] = "must-revalidate"
response.headers["Pragma"] = "must-revalidate"
response.headers["Content-type"] = "application/csv"

如果您没有添加内容类型,FF48.0将其报告为html,并为HTML打开一次保存对话框,然后为CSV打开一次。 如果您不添加缓存控制,您的结果可能会被缓存,如果您提供活动内容,这不是您想要的。 如果您使用没有年龄的must-revalidate,它将有效地充当no-cache-请参阅herehere以获取解释。

相似问题