form action in flask not redirecting to the route

Viewed 2000

Simply I am just trying to redirect to an url by using the below code in my login.html template:

     <form>
          <form action="/sessions">      
          <p>Username:</p>
          <p><input type="text" minlength="8" name="username"required /></p>
          <p>Password:</p>
          <p><input type="text" name="password"/></p>
          <input type="submit" value="Submit">
    </form> 

and

def login():
    print("inside login")
    return render_template('login.html')


@app.route("/sessions", methods=["GET","POST"])
def sessions():
    userid  = request.form.get("userid")
    password  = request.form.get("password")
    return request.form.get("userid"), request.form.get("password")

but is stuck on the login() url. Also I tried

 <form action="{{ url_for('sessions') }}">

but is not working as well. Not sure what I am missing? Please any hints/ideas would be highly appreciated.

2 Answers

Try this ( i just added one more line, the commented one):

@app.route("/sessions", methods=["GET","POST"])
def sessions():
    userid  = request.form.get("userid")
    password  = request.form.get("password")
    if request.method == 'POST':  #additional line
        return request.form.get("userid"), request.form.get("password")

Updated answer reflects new comments

Found couple issues in your code:

  1. HTML form is incorrect, you are using form in form
     <form>
          <form action="/sessions">      
          <p>Username:</p>
          <p><input type="text" minlength="8" name="username"required /></p>
          <p>Password:</p>
          <p><input type="text" name="password"/></p>
          <input type="submit" value="Submit">
    </form> 

You should change it to this


<html>
    <body>
        <h1>This is login page</h1>
        <form action="{{ url_for('login') }}" method="POST">
            <p>Username:</p>
            <p><input type="text" minlength="8" name="username"required /></p>
            <p>Password:</p>
            <p><input type="text" name="password"/></p>
            <input type="submit" value="Submit">
        </form> 
    </body>
</html>

Notice changes, first there is only 1 form tag, then I use jinja2 engine to call the login in form.action, 2nd this login page handles serving login HTML when there is a GET request (initially opening this page) and for accepting form POST request with credentials.

Then I changed the routes to this:

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        user_name = request.form['username']
        password = request.form['password']
        print(user_name, password)  # do something here?
        return redirect(url_for('session'))
    return render_template('login.html')


@app.route('/session')
def session():
    return render_template('session.html')

Notice that now login accepts both methods, GET and POST, as mentioned before, GET is for serving HTML content and POST is for submitting form data. In the login endpoint I have a condition that checks, if it's a POST method request, then I extract credential details from request.form and after doing something (e.g. in that print() statementIreturn redirect(url_for('session'))`.

This is how you manage redirects from one page to another by clicking submit on one of a pages.

original answer that was incorrect

In Flask to redirect, you could you something like this:

from flask import url_for, redirect

@app.route('/sessions', methods['GET', 'POST']
def sessions():
    # some code
    return redirect(url_for('some.endpoint'))

This will redirect you to a specific endpoint that you will provide. In the docs there is more info about it.

Related