I (mostly) followed Per Wagner Nielsen's excellent tutorial, but then tried (and failed) to add a boolean field to the form. Every user created with the Signup form seems to have the boolean value set to True even though the default is False and the checkbox is unchecked on form submit. I test that with the line in the login controller if user.is_admin()
, and the controller does return user is admin
. I'm showing all the code because I really don't see where my error lies -- sorry if that's too much. Any help is greatly appreciated.
app.py
from flask import Flask, reque,st, render_template, redirect, url_for, flash, g
from forms import SignupForm, LoginForm
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, login_user, login_required, logout_user
from flask.ext.login import current_user
app = Flask(__name__)
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
######################################################################
# Models
######################################################################
class User(db.Model):
email = db.Column(db.String(80), primary_key=True, unique=True)
password = db.Column(db.String(80))
is_admin = db.Column(db.Boolean, default=False)
def __init__(self, email, password, is_admin):
self.email = email
self.password = password
self.is_admin = is_admin
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return str(self.email)
def is_admin(self):
if self.is_admin:
return True
else:
return False
def __repr__(self):
return '<User %r>' % self.email
######################################################################
@login_manager.user_loader
def load_user(email):
return User.query.filter_by(email = email).first()
@app.before_request
def before_request():
g.user = current_user
######################################################################
# Routes
######################################################################
@app.route('/')
def index():
return "Welcome to Flask"
@app.route('/signup', methods=['GET', 'POST'])
def signup():
form = SignupForm()
if request.method == 'GET':
return render_template('signup.html', form = form)
elif request.method == 'POST':
if form.validate_on_submit():
if User.query.filter_by(email=form.email.data).first():
return "Email address already exists"
else:
newuser = User(form.email.data, form.password.data, form.is_admin.data)
db.session.add(newuser)
db.session.commit()
return "User created"
else:
#return "Form didn't validate"
return render_template('signup.html', form=form)
@app.route('/login', methods=['GET','POST'])
def login():
form = LoginForm()
if request.method == 'GET':
return render_template('login.html', form=form)
elif request.method == 'POST':
if form.validate_on_submit():
user=User.query.filter_by(email=form.email.data).first()
if user:
if user.password == form.password.data:
login_user(user)
#return "User logged in"
if user.is_admin():
return "user is admin"
else:
return "user is not admin"
else:
return "Wrong password"
else:
return "user doesn't exist"
else:
return "form not validated"
@app.route("/logout")
@login_required
def logout():
logout_user()
return "Logged out"
@app.route('/protected')
@login_required
def protected():
return "protected area, user: " + current_user.email + ", " + str(g.user.is_admin)
######################################################################
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80, debug=True)
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, validators, BooleanField
from wtforms.validators import Email, DataRequired
class SignupForm(FlaskForm):
email = StringField('Email',
[DataRequired(),Email()])
password = PasswordField(
'Password',
[DataRequired()])
is_admin = BooleanField('Is an Admin')
submit = SubmitField("Sign In")
class LoginForm(FlaskForm):
email = StringField('Email',
[DataRequired(),Email()])
password = PasswordField(
'Password',
[DataRequired()])
submit = SubmitField("Sign In")
templates/signup.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Access</title>
</head>
<body>
<h1>Sign-up</h1>
<form method="POST" action="/signup">
{{ form.hidden_tag() }}
{{ form.email.label }} {{ form.email(size=20) }}<br>
{{ form.password.label }} {{ form.password(size=20) }}<br>
{{ form.is_admin.label }} {{ form.is_admin() }}<br>
<input type="submit" value="Signup">
</form>
<h1>Form Errors</h1>
{{ form.errors }}
</body>
</html>
templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form method="POST" action="/login">
{{ form.hidden_tag() }}
{{ form.email.label }} {{ form.email(size=20) }}
{{ form.password.label }} {{ form.password(size=20) }}
<input type="submit" value="login">
</form>
</body>
</html>