[英]Python Flask: getting URL when moving to production
I'm using Python from quite some time but I am totally newbie in Flask.我使用 Python 已经有一段时间了,但我是 Flask 的新手。 Can you help me with two simple questions I have been strugling two days?
你能帮我解决我这两天纠结的两个简单问题吗?
I have a simple Flask app that supposed to import a XLSX or CSV, parse it and create a zip file to download.我有一个简单的 Flask 应用程序,它应该导入 XLSX 或 CSV,解析它并创建一个 zip 文件以供下载。 While I am begginig work on the parse part, I got an error when uploading the file, and I found out that the app is not saving the file altough it works when running flask locally .
当我开始解析部分的工作时,上传文件时出现错误,我发现应用程序没有保存文件,尽管它在本地运行 flask 时工作。 This is the code:
这是代码:
test2.py测试2.py
``` from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import pandas as pd
app = Flask(__name__)
def work(arquivo):
df = pd.read_excel(arquivo)
return(str(df.shape))
@app.route('/')
def start():
return "acesse /upload"
@app.route('/upload')
def upload_file():
return render_template('upload.html')
@app.route('/uploader', methods = ['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
f.save('./inbox/'+secure_filename(f.filename))
a = work('./inbox/'+secure_filename(f.filename))
return 'file uploaded successfully '+a
if __name__ == '__main__':
app.run(debug = True)
```
And this is the upload.html file that I put on templates folder in production (the app runs on http://www.fabianocastello.com.br/test2/upload ):这是我在生产中放在模板文件夹中的upload.html文件(应用程序在http上运行://www.fabianocastello.com.br/test2/ )
<html>
<body>
<form action = "http://www.fabianocastello.com.br/test2/uploaded" method = "POST"
enctype = "multipart/form-data">
<p>Arquivo</p>
<input type = "file" name = "file" accept=".csv, .xlsx" </input>
<input type = "submit" value="Enviar arquivo"/>
</form>
</body>
</html>
when locally, the upload.html file that works is this:在本地时,有效的 upload.html 文件是这样的:
<html>
<body>
<form action = "http://localhost:5000/uploader" method = "POST"
enctype = "multipart/form-data">
<p>Arquivo</p>
<input type = "file" name = "file" accept=".csv, .xlsx" </input>
<input type = "submit" value="Enviar arquivo"/>
</form>
</body>
</html>
The error I got after uploading the file is this: Not Found The requested URL was not found on the server.上传文件后我得到的错误是: Not Found The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
如果您手动输入了 URL,请检查您的拼写并重试。
My questions are these: 1. Why the production app is not saving the uploaded file in "inbox" folder?我的问题是: 1. 为什么生产应用程序没有将上传的文件保存在“收件箱”文件夹中? 2. Is there a way that I substitute the URL in upload.html file from a variable so to I do not have to manually change the file before upload?
2. 有没有一种方法可以将upload.html 文件中的URL 替换为变量,这样我就不必在上传前手动更改文件?
Thank you all in advance.谢谢大家。
This is what the url_for
method is for.这就是
url_for
方法的用途。 That will automatically fix "http://localhost:5000/uploader"
for you.这将自动为您修复
"http://localhost:5000/uploader"
。
However, <form action = "http://www.fabianocastello.com.br/test2/uploaded"...>
points at a bigger misunderstanding.但是,
<form action = "http://www.fabianocastello.com.br/test2/uploaded"...>
指出了更大的误解。 It would be horrendous if you had to alter every route in your templates moving from development to production.如果您必须更改模板中从开发到生产的每条路线,那将是可怕的。 Your Flask routes needn't point to the specific domain that you're running your app on;
您的 Flask 路由不必指向您正在运行应用程序的特定域; they need only point to the endpoint of the server running your app (which might be
gunicorn
, for example).它们只需要指向运行您的应用程序的服务器的端点(例如可能是
gunicorn
)。 The Mega Tuorial might be helpful here for deployment. Mega Tuorial在这里可能有助于部署。 There's also more info in the deployment docs .
部署文档中还有更多信息。
With that out of the way, there's other issues that need to be dealt with:有了这些,还有其他问题需要处理:
upload_file
.upload_file
。 Why?upload_file
is set to accept both GET
and POST
requests, but you only handle the POST
case.upload_file
设置为接受GET
和POST
请求,但您只处理POST
情况。 Sending a GET
request to this route will error.GET
请求会出错。 This fixes the form:这修复了表单:
<html>
<body>
<form action = "{{ url_for('upload_file') }}" method = "POST"
enctype = "multipart/form-data">
<p>Arquivo</p>
<input type = "file" name = "file" accept=".csv, .xlsx" </input>
<input type = "submit" value="Enviar arquivo"/>
</form>
</body>
</html>
This consolidates the two route functions into one:这将两个路由功能合并为一个:
@app.route('/uploader', methods = ['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
f.save('./inbox/'+secure_filename(f.filename))
a = work('./inbox/'+secure_filename(f.filename))
return 'file uploaded successfully '+a
else:
return render_template('upload.html')
return 'file uploaded successfully '+a
is going to give a garbage result, if any, though. return 'file uploaded successfully '+a
会给出一个垃圾结果,如果有的话。 It's not going to render a template with the message, it's just going to be unstyled text.它不会用消息呈现模板,它只是无样式的文本。 It looks like you want AJAX, which would look something like this:
看起来你想要 AJAX,它看起来像这样:
<html>
<body>
<form action = "{{ url_for('upload_file') }}" method = "POST"
enctype = "multipart/form-data" id="upload_file_form">
<p>Arquivo</p>
<input type = "file" name = "file" accept=".csv, .xlsx" </input>
<input type = "submit" value="Enviar arquivo"/>
</form>
<div id="response_div"></div>
</body>
<script>
$("#upload_file_form").submit(function(e) {
e.preventDefault();
var form = $(this);
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: form.serialize(),
context: form,
success: function(resp) {
$("#response_div").html(resp);
}
});
});
</script>
</html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.