Reputation: 15526
This is the view function used to generate a file upload form and process it (yes this comes directly from the Flask docs):
transaction_blueprint = Blueprint(
"transaction", __name__, template_folder="../templates", url_prefix="/transactions"
)
@transaction_blueprint.route("/upload", methods=["GET", "POST"])
def upload_select_file():
print(request.method)
if request.method == "POST":
# check if the post request has the file part
if "file" not in request.files:
flash("No file part")
return redirect(request.url)
file = request.files.get("file")
# if user does not select file, browser also
# submit an empty part without filename
if file.filename == "":
flash("No selected file")
return redirect(request.url)
# allowed_file is defined elsewhere
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join("/tmp", filename))
return jsonify({"success": True})
return """
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
<p>%s</p>
""" % "<br>".join(os.listdir("/tmp",))
Upon submitting the form from http://localhost:8000/transactions/upload
, I receive the 400 bad request error. I am testing with a simple text file that is about 15kb in size. As far as I can tell, the HTML is well formed:
<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
I've searched for two days and learned this error occurs when the file input's name
attribute is not found in the Flask view endpoint. I handle for that using request.files.get("file")
. Further In my case, upon submitting the form, the method is not being reached (server log does not even print "POST
"). This makes sense as the 400 is a client error but still...
Is there something with using Blueprints that's breaking this? What am I doing wrong here?
Upvotes: 1
Views: 1357
Reputation: 15526
Adding the csrf token did it...
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
Upvotes: 1