skip to Main Content

I’m currently working on a 100 days of code project however I’m stuck. I’m unable to render the "Success.html" and "Denied.html" templates in my login route code. I’m including the python and html portions of the code. Any insight is appreciated. I think the problem is inside the login route code however I’ve hit a wall and don’t know what to try at the moment.

import email_validator
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from flask_wtf.csrf import CSRFProtect
from wtforms.validators import Email, Length, DataRequired, ValidationError
from wtforms import StringField, PasswordField, SubmitField
from email_validator import validate_email

# create a flask instance
app = Flask(__name__)

# CSRF protection
app.secret_key = "123456"
#disabling CSRF Protection
# app.config['WTF_CSRF_ENABLED'] = False


# create a form class
class LoginForm(FlaskForm):
    def validate_email(self, field):
        # Custom email validation using email_validator
        try:
            validate_email(field.data)
        except Exception as e:
            raise ValidationError(str(e))

    email = StringField(label="Email", validators=[DataRequired(), Email()], render_kw={"size": 30})
    password = PasswordField(label="Password", validators=[DataRequired(), Length(min=8)], render_kw={"size": 30})
    submit = SubmitField(label="Log In")


# create a route decorator
@app.route('/', methods=["GET", "POST"])
def login():
    form = LoginForm()
    form.validate_on_submit()
    print(request.method)
    print(form.email.data)
    print(form.password.data)

    return render_template('login.html', form=form)


@app.route('/login', methods=["GET", "POST"])
def login_info():
    form = LoginForm()
    if form.validate_on_submit():
        if form.email.data == "[email protected]" and form.password.data == "12345678":
            print(request.method)
            print(type(form.email.data))
            print(type(form.password.data))
            return render_template('success.html')
        else:
            return render_template('denied.html')
    else:
        return render_template('login.html', form=form)



if __name__ == "__main__":
    app.run(debug=True)

The HTML code for the login page is this

<!DOCTYPE HTML>

<html>
    <head>
        <title>Login</title>
    </head>
    <body>
        <div class="container">
        <h1>Login Page</h1>
        <form method="post" action="{{ url_for('login')}}" novalidate>
    {{form.csrf_token}}
    <p>
        {{form.email.label}} <br> {{form.email}}
        {% for err in form.email.errors %}
        <span style="color:red">{{ err }}</span>
        {% endfor %}
    </p>
    <p>
        {{form.password.label}} <br> {{form.password}}
        {% for err in form.password.errors %}
        <span style="color:red">{{ err  }}</span>
        {% endfor %}
    </p>
    {{form.submit}}
        </form>
        </div>
    </body>
</html>

2

Answers


  1. You’re submitting your form to the wrong endpoint. The form’s action attribute references login, not login_info.

    Login or Signup to reply.
  2. Typically you’ll want the GET to the login view to just provide the form (login.html) and the POST to processes the submitted login details and then redirect the user where you want them to go (or just show success.html in your case).

    You’ve somewhat complicated things by having 2 views that both take GET and POST but the login_info one isn’t referenced anywhere in your login.html so it’s never actually used. The login view calls .validate_on_submit() but then always just returns the login.html and that’s why you don’t ever see success.html.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search