In my Flask app I have user management done via flask.session
. So all info about logged in user is stored in session
. When some new user registers, in database I create new row with one attribute being verified
set to false and the same information is stored in session['user']['verified']
. When user browses the website, no matter which endpoint, I want to flash
him a message, that he still did not verify his email address.
So far I managed to do this by creating @after_request
method like so:
@app.after_request def check_user_verification_status(response): try: if not session['user']['verified']: flash("Your email address is still not verified, ...") except Exception: pass return response
This way the flash message really appears on all endpoints, but sometimes it appears duplicated because of some redirects being made. I solved the duplication problem following this answer: Flask – duplicates flash messages
But when I am on main page and click on logout button, which redirects to endpoint logout
(the endpoint logs out user – deletes user info from session – and redirects to main page), the flash message about not verified user also appears, even when no user is then technically logged in, because of finished original request, which was processed just before the redirect to logout endpoint and there was still user info in session.
Is there some solution to this problem. Something like “After request for all endpoints which will be called only once after all redirects” so it flashes the message just once (or zero times when the condition is not met)?
Advertisement
Answer
At the end I solved current problem by editing of my layout.html
page.
Every Jinja template in my app uses layout so the solution was to use simple Jinja if statement, which asked for verified
variable. If it is true, it just shows div
with message informing user, that email address is not verified. I added to the div
the same class as classic flash messages have and this way it looks exactly the same as flash message.
{% if not verified %} <div class="msg info">Your email address is still not verified, ...</div> {% endif %}
And the verified
variable is always refreshed in @before_request
method and set to g.verified
(global variable – flask.g
). This is then passed to every Jinja template (every endpoint) by overriding render_template()
method as follows:
import flask from flask import g @app.before_request def set_user_info(): g.verified = is_user_verified() def render_template(template, **kwargs): return flask.render_template(template, verified=g.config, **kwargs)
It may not be the best solution, but I like it a bit more than solution mentioned in comment below the question.