Ad

Flask, Jinja2 And WTForms - One Method For All URLs?

I am building a simple website with Flask, where the user login form is available in the upper right corner, no matter on which url the user currently is (html form is defined in my base.html template, which is extended by all other templates). So one of the choices to make it work, is to handle the login form in each @app.route() method, but it adds a lot of redundant code, it looks ugly, and I'm looking for a way to simplify it.

So my question is: Is it possible to create one method that will handle the login form for each endpoint in my application?

Here is some code of my login form:

@app.route('/', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
    return redirect(url_for('home'))

form = LoginForm()
if form.validate_on_submit():
    user = User.query.filter_by(username=form.username.data).first()

    if user is None or not user.check_password(form.password.data):
        flash('Invalid username or password')
        return redirect(url_for('login'))

    login_user(user, remember=True)
    return redirect(url_for('home'))

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

And here is the screenshot of the rendered form itself:

https://i.stack.imgur.com/PXNSB.png

EDIT:

So far I came up only with this, but is there any better solution? (The endpoint argument is to redirect the user back to the page where he logged from)

# method used in each URL for login purpose
def login_function(form, endpoint):
user = User.query.filter_by(username=form.username.data).first()

if user is None or not user.check_password(form.password.data):
    flash('Invalid username or password')
    return redirect(url_for(endpoint))

login_user(user, remember=True)
return redirect(url_for(endpoint))

And that method is accessed in each URL like this:

login_form = LoginForm()
if login_form.validate_on_submit():
    return login_function(login_form, 'home')
Ad

Answer

You may have tried this already, or it's not actually what you're looking for, but your form action should go to a single routing that handles your form request and then redirects them wherever. So it will use the same request handling no matter where you use the same form action. The code would be like this: html:

<form action='login'>Form Here</form>

python:

@app.route('/login', methods=['POST'])
def login():
    if request.method == "POST":
        //handle form data

Every time they try to log in, it should use that code no matter where they are on the site. Hope this helps!

Ad
source: stackoverflow.com
Ad