'werkzeug.routing.BuildError: Could not build url for endpoint 'success'. Did you forget to specify values ['name']?
"werkzeug.routing.BuildError: Could not build url for endpoint 'success'. Did you forget to specify values ['name']?"
How to solve this error? I have tried many things but can't solve it by myself.
http_methods.py:
from flask import Flask, redirect, url_for, request
app = Flask(__name__)
@app.route('/success/<name>')
def success(name):
return 'welcome %s' % name
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
user = request.form['nm']
return redirect(url_for('success', name = user))
else:
user = request.args.get('nm')
return redirect(url_for('success', name = user))
if __name__ == "__main__":
app.run(debug=True)
I get an error in the login method, that value of ['name'] is not specified; how to solve this error?
login.html:
<!DOCTYPE html>
<html lang="en">
<body>
<form action="http://127.0.0.1:5000/login" method="POST">
<p>Enter name:</p>
<p><input type="text" name="nm" value="nm"/></p>
<p><input type="submit" value="submit"/></p>
</form>
</body>
</html>
output:
File "/Users/chirag.kanzariya/pythonprojects/v_python/lib/python3.7/site-packages/flask/helpers.py", line 345, in url_for
force_external=external)
File "/Users/chirag.kanzariya/pythonprojects/v_python/lib/python3.7/site-packages/werkzeug/routing.py", line 1776, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.BuildError: Could not build url for endpoint 'success'. Did you forget to specify values ['name']?
127.0.0.1 - - [29/Jan/2019 14:48:00] "GET /login?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
127.0.0.1 - - [29/Jan/2019 14:48:00] "GET /login?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
127.0.0.1 - - [29/Jan/2019 14:48:00] "GET /login?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
127.0.0.1 - - [29/Jan/2019 14:48:00] "GET /login?__debugger__=yes&cmd=resource&f=ubuntu.ttf HTTP/1.1" 200 -
127.0.0.1 - - [29/Jan/2019 14:48:00] "GET /login?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
127.0.0.1 - - [29/Jan/2019 14:48:00] "GET /login?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
I am using python 3.7 and flask 1.0.2 version right now.
Solution 1:[1]
You need to add in the else section (GET), the html code for your login.
from flask import Flask, request, render_template, redirect, url_for
app = Flask(__name__)
@app.route('/success/<name>')
def success(name):
return 'welcome %s' % name
@app.route('/login',methods = ['POST', 'GET'])
def login():
if request.method == 'POST':
user = request.form['nm']
return redirect(url_for('success',name = user))
else:
return render_template('login.html')
if __name__ == '__main__':
app.run(debug = True)
Solution 2:[2]
The tutorial from which this code originates has a logical flaw, identified and rectified by the initial two contributors gittert and eduardosufan. This vexed me too, but I couldn't work out whether it was just my poor understanding of Flask, or whether there was genuinely a problem with the tutorial, until I came across this Stack Overflow question, which confirmed the latter.
Specifically, the logic initially checks for a POST request. If it's not that, it assumes a GET - and crucially, also the value of nm. Here's the flaw: if the user has not yet entered a name, then its value will be None, for which Werkzeug can't create a route, and that prevents the page from even being loaded - chicken and egg.
Solution 3:[3]
The anchor tag in the HTML file being rendered should reference the function that it is being directed to. For example following the code snippet below, if we want to reference index in HTML, the flask app "app.py" must contain a function called index.
I have added the about function to clarify what I mean.
from flask import Flask, render_template
app = FLASK(__name__)
@app.route('/')
def index():
return render_template('home.html')
@app.route('/')
def about():
return render_template('about.html')
<a href="{{url_for('index')}}">Index</a>
to
<a href="{{url_for('about')}}">Index</a>
Solution 4:[4]
You're trying to access the login directly. You first have to open the html page. then it accesses the value. try this fix and open the html page first
@app.route('/login',methods=["POST","GET"])
def login():
if request.method=="POST":
user=request.form["nm"]
else:
user=request.args.get("nm")
if user:
return redirect(url_for('success', name = str(user)))
else:
return "go to the form"
Solution 5:[5]
There's nothing wrong with your code, all you need to do is navigate to the folder containing your .py code and the html file containing the form (ensuring they are in the same folder) and run the html file, complete the form and submit. the server takes care of the connection between the python code and html code using the link passed in action. I hope it helps.I battled with this very same issue, all suggested responses work only if you run your html code first not just the .py script.
Solution 6:[6]
For blueprint routes as a module check url_for function in HTML template
<a href="{{url_for('index')}}">Index</a>
to
<a href="{{url_for('auth.index')}}">Index</a>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | eduardosufan |
| Solution 2 | Angus McAllister |
| Solution 3 | Hanzo Hasashi |
| Solution 4 | PRABAL KALIA |
| Solution 5 | Justice Nxumalo |
| Solution 6 | Özgür BAYRAM |
