I've managed to get flask-login working but when I try use, for example current_user.username
in my templates the value is None
I suspect this is to do with my User.get() function but cannot for the life of my understand what I need to do so I can access the current users username
or email
and so on.
So the question is, why are the rest of my current_user attributes like username
, not getting populated?
Note the get function
from sqlalchemy import Column, Integer, String
from flask_login import UserMixin
from database import Base
class User(Base, UserMixin):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String(80), unique=True)
password = Column(String(80))
email = Column(String(120), unique=True)
def __init__(self, id):
self.id = id
def __repr__(self):
return '<User %r>' % self.username
@classmethod
def get(cls, id):
"""Return user instance of id, return None if not exist"""
try:
return cls(id)
except UserWarning:
return None
Note the load_user, I believe the flask documents expect this to be present and for it to take an ID as input
import flask
from flask_login import login_user, logout_user, login_required
from reportr import app, login_manager
from models import User
from forms import UploadForm, LoginForm
from database import init_session
@login_manager.user_loader
def load_user(id):
return User.get(id)
@app.route('/', methods=('GET', 'POST'))
def index():
return flask.render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
del form.email # Don't want the email address on the form
if form.validate_on_submit():
session = init_session()
user = session.query(User).filter(User.username == flask.request.form['username']).first()
if user and user.password == flask.request.form['password']:
login_user(user)
flask.flash('Logged in successfully.', 'info')
else:
flask.flash('Username or password incorrect.', 'error')
return flask.redirect(flask.url_for('login'))
return flask.redirect(flask.url_for('index'))
return flask.render_template('login.html', form=form)
@app.route('/logout')
def logout():
logout_user()
return flask.redirect(flask.url_for('index'))
@app.route('/upload/results', methods=('GET', 'POST'))
def upload_results():
form = UploadForm()
if not form.validate_on_submit():
flask.flash('Please fill out all required fields', 'error')
return flask.render_template('upload_results.html', form=form)
@app.route("/settings")
@login_required
def settings():
pass
In here I am using current_user.id, this works.
{% block navbar %}
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="{{ url_for('.index') }}"><span class="glyphicon-play" aria-hidden="true"></span>Reportr!</a>
</div>
<div class="navbar-collapse collapse click-nav">
<ul class="nav navbar-nav no-js">
<li class="dropdown">
<a id='browse_menu' href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Browse <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li>
<a id='browse_by_project' href="#">By Project</a>
</li>
</ul>
<li class="dropdown">
<a id='upload_menu' href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Upload <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li>
<a id='upload_test_results' href="{{ url_for('.upload_results') }}">Test Results</a>
</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated() %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ current_user.id }} <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="{{ url_for('.settings') }}">Settings</a></li>
<li class="divider"></li>
<li><a href="{{ url_for('.logout') }}">Logout</a></li>
</ul>
</li>
{% else %}
<li>
<a id='login' href="{{ url_for('.login') }}">Login</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
{% endblock %}
I've found the source of the issue.
My load_user()
function was not returning a user, rather an instance of the user class with only the id
populated.
I changed my load_user function to query the table and return the an instance of the user, instead the class and now it is working.
See below:
@login_manager.user_loader
def load_user(user_id):
try:
return User.query.get(user_id)
except:
return None
I also got rid of the get()
function on my model as that is not needed and it is much simpler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With