I am new to python coding but straightaway started experimenting with flask. I am having trouble with flask-login extension Here I am making a simple application which is a blog. This blog is going to be used by one person only.
I cannot understand why the user_loader decorator not working which is defined in models.py. I get exception the application NoneType object is not callable. My app structure is like this
.
|-- app
| |-- admin
| | |-- __init__.py
| | |-- static
| | |-- templates
| | `-- views.py
| |-- config.py
| |-- __init__.py
| |-- main
| | |-- __init__.py
| | |-- static
| | |-- templates
| | `-- views.py
| `-- models.py
`-- launch.py
app.init
from flask import Flask
from main import main
from admin import admin
from flask.ext.script import Manager
from .config import config
from flask_debugtoolbar import DebugToolbarExtension
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy import Column
from flask_bootstrap import Bootstrap
from flask.ext.moment import Moment
from flask.ext.login import LoginManager
app_myblog=Flask(__name__)
app_myblog.debug=True
app_myblog.config.from_object(config)
app_myblog.register_blueprint(main)
app_myblog.register_blueprint(admin,url_prefix="/admin"
toolbar=DebugToolbarExtension(app_myblog)
manager=Manager(app_myblog)
db=SQLAlchemy(app_myblog)
Bootstrap(app_myblog)
moment=Moment(app_myblog)
login_manager=LoginManager()
login_manager.init_app(app_myblog)
login_manager.session_protection='strong'
login_manager.login_view='admin.login'
In app.models I have defined User class which does not load users from database. In fact it simply loads user from configuration. In same file I have also defined user_loader callback
class User(UserMixin):
def __init__(self):
self.id='1'
self.name=app_myblog.config['USERNAME']
self.password=app_myblog.config['PASSWORD']
def get_id(self):
return unicode(id)
@login_manager.user_loader
def load_user(userid):
u=User()
if u.get_id()==userid:
return u
else:
return None
admin.init
from flask import Blueprint
admin=Blueprint('admin',__name__,template_folder='templates',static_folder='static')
from . import views
admin.views
from flask import render_template,request,redirect,url_for
from . import admin
from flask.ext.login import login_required,login_user
from flask_wtf.form import Form
from wtforms import StringField,PasswordField,SubmitField
from ..models import User
class LoginForm(Form):
username=StringField('Username')
password=PasswordField('Password')
submit=SubmitField('Login')
@admin.route('/')
@login_required
def index():
return render_template('admin_home.html')
@admin.route('/login',methods=['GET','POST'])
def login():
form=LoginForm()
if form.validate_on_submit():
login_user(User())
nextx = request.args.get('next')
return redirect(nextx or url_for('admin.index'))
return render_template('admin_login.html',form=form)
Whenever i run the routes which have login_required i get the error TypeError: 'NoneType' object is not callable. Here is the traceback.
Traceback (most recent call last):
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask_debugtoolbar/__init__.py", line 125, in dispatch_request
return view_func(**req.view_args)
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask_login.py", line 756, in decorated_view
elif not current_user.is_authenticated():
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask_login.py", line 46, in <lambda>
current_user = LocalProxy(lambda: _get_user())
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask_login.py", line 794, in _get_user
current_app.login_manager._load_user()
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask_login.py", line 363, in _load_user
return self.reload_user()
File "/home/shivam/Workspaces/PythonWorkSpace/MyBlog/venv/lib/python2.7/site-packages/flask_login.py", line 325, in reload_user
user = self.user_callback(user_id)
TypeError: 'NoneType' object is not callable
Edit: I created a minimal example of your code and the the difference was that I removed the
get_id(self)
function (+ some extra libraries that isn't needed), beacuse it's part of theUserMixin
class that you inherit.Are you sure your form is getting validated? Can you describe how you test this step by step? I mean, "go to login.html" -> "enter credentials" -> etc
Make sure which call is causing the crash, is it the
redirect
inside your login function?