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')
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!
Related Questions
- → What are the pluses/minuses of different ways to configure GPIOs on the Beaglebone Black?
- → Django, code inside <script> tag doesn't work in a template
- → React - Django webpack config with dynamic 'output'
- → GAE Python app - Does URL matter for SEO?
- → Put a Rendered Django Template in Json along with some other items
- → session disappears when request is sent from fetch
- → Python Shopify API output formatted datetime string in django template
- → Can't turn off Javascript using Selenium
- → WebDriver click() vs JavaScript click()
- → Shopify app: adding a new shipping address via webhook
- → Shopify + Python library: how to create new shipping address
- → shopify python api: how do add new assets to published theme?
- → Access 'HTTP_X_SHOPIFY_SHOP_API_CALL_LIMIT' with Python Shopify Module