Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

werkzeug.routing.BuildError: Could not build url for endpoint 'success'. Did you forget to specify values ['name']?

Tags:

python

flask

"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.

like image 595
Chirag Kanzariya Avatar asked Jan 29 '19 09:01

Chirag Kanzariya


3 Answers

Have a look at this. In your login function I added a render_template for the first GET request when opening the login page. This will probably also prevent the error you're getting now. Bear in mind this does not contain any error handling, like what happens if user is unknown in your login procedure.

@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))

    return render_template(login.html)

if __name__ == "__main__":
    app.run(debug=True)
like image 88
gittert Avatar answered Oct 22 '22 01:10

gittert


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)
like image 4
eduardosufan Avatar answered Oct 21 '22 23:10

eduardosufan


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.

like image 4
Angus McAllister Avatar answered Oct 22 '22 01:10

Angus McAllister