-
Notifications
You must be signed in to change notification settings - Fork 8
Commit v0.23
kwmccabe edited this page Apr 17, 2018
·
8 revisions
v0.23 - Add fields user_email and user_pass
- +2 -1 [M] mysql/scripts/seeddata.sql
- +6 -3 [M] mysql/scripts/tables.sql
- +16 -3 [M] web/app/user/forms.py
- +20 -2 [M] web/app/user/models.py
- +12 -0 [M] web/app/user/templates/user_create.html
- +13 -1 [M] web/app/user/templates/user_edit.html
- +5 -2 [M] web/app/user/views.py
- Update seed data for column
user.user_email
.
DELETE FROM `user`;
-INSERT INTO `user` (keyname) VALUES ("admin");
+INSERT INTO `user` (active,keyname,user_email) VALUES (True,"admin","admin@flaskapp.com");
+INSERT INTO `user` (active,keyname,user_email) VALUES (False,"user","user@flaskapp.com");
OPTIMIZE TABLE `user`;
- Add column
user_email
. - Add column
user_pass
.
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
- `keyname` varchar(63) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
+ `keyname` varchar(63) NOT NULL,
+ `user_email` varchar(255) DEFAULT NULL,
+ `user_pass` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_keyname` (`keyname`),
- KEY `user_active` (`active`)
+ KEY `user_active` (`active`),
+ KEY `user_email` (`user_email`)
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8;
DESCRIBE `user`;
SELECT "table `user` created" AS MSG;
- Add
user_email
toCreateUserForm
andEditUserForm
. - Add
password
andpassword2
toCreateUserForm
andEditUserForm
. - Create methods
filter_useremail()
andvalidate_usermail()
.
-from wtforms.validators import Email, InputRequired, Length
+from wtforms.validators import Email, EqualTo, InputRequired, Length
...
+def filter_useremail(data):
+ return str(data).lower()
+
...
+def validate_usermail(self, field):
+ if field.data != self.user.user_email and \
+ UserModel.query.filter_by(user_email=field.data).first():
+ raise ValidationError('Email address already in use.')
...
class CreatUserForm(FlaskForm):
keyname = StringField('Username', validators=[InputRequired(),Length(2,63),validate_username], filters=[filter_username])
+ user_email = StringField('Email', validators=[InputRequired(),Length(1,63),Email(),validate_usermail], filters=[filter_useremail])
+ password = PasswordField('Password', validators=[InputRequired(),Length(1,31),EqualTo('password2',message="Passwords must match.")])
+ password2 = PasswordField('Confirm Password')
submit = SubmitField('Create User')
...
class EditUserForm(FlaskForm):
id = HiddenField('id')
- keyname = StringField('Username', validators=[InputRequired(),Length(2,63),validate_username], filters=[filter_username])
active = BooleanField('Active')
+ keyname = StringField('Username', validators=[InputRequired(),Length(2,63),validate_username], filters=[filter_username])
+ user_email = StringField('Email', validators=[InputRequired(),Length(1,63),Email(),validate_usermail], filters=[filter_useremail])
+ password = PasswordField('Password', validators=[EqualTo('password2',message="Passwords must match.")])
+ password2 = PasswordField('Confirm Password')
submit = SubmitField('Update User')
- Add columns
user_email
anduser_pass
toUserModel
. - Add method to set
user_pass
via pseudo-columnpassword
and werkzeug'sgenerate_password_hash()
. - Add method
verify_password()
using werkzeug'scheck_password_hash()
.
+import logging
+
from flask import url_for
+from werkzeug.security import generate_password_hash, check_password_hash
from .. import db
class UserModel(db.Model):
__tablename__ = 'user'
id = db.Column(db.BigInteger, autoincrement=True, primary_key=True)
- keyname = db.Column(db.String(63), nullable=False, unique=True, index=True, default='')
active = db.Column(db.Boolean, nullable=False, index=True, default=1)
+ keyname = db.Column(db.String(63), nullable=False, unique=True, index=True, default='')
+ user_email = db.Column(db.String(255), nullable=False, unique=True, index=True)
+ user_pass = db.Column(db.String(128))
+
+ @property
+ def password(self):
+ raise AttributeError('password is not readable')
+
+ @password.setter
+ def password(self, password):
+ logging.debug( "password.setter(%s)" % self.user_email)
+ self.user_pass = generate_password_hash(password)
+
+ def verify_password(self, password):
+ return check_password_hash(self.user_pass, password)
def to_json(self):
json_user = {
#'url': url_for('api.get_user', id=self.id),
'id' : self.id,
- 'keyname' : self.keyname,
'active' : self.active,
+ 'keyname' : self.keyname,
+ 'user_email': self.user_email,
}
return json_user
- Add
user_email
form field. - Add
password
form field. - Add
password2
form field.
+ <div class="form-group">
+ *{{ form.user_email.label }}
+ {{ form.user_email(class_='form-control',placeholder='a@b.c') }}
+ </div>
+ <div class="form-group">
+ *{{ form.password.label }}
+ {{ form.password(class_='form-control',placeholder='password') }}
+ </div>
+ <div class="form-group">
+ *{{ form.password2.label }}
+ {{ form.password2(class_='form-control',placeholder='confirmation') }}
+ </div>
{{ form.submit(class_='btn btn-primary') }}
- Add
user_email
form field. - Add
password
form field. - Add
password2
form field.
<div class="form-group">
*{{ form.keyname.label }}
- {{ form.keyname(class_='form-control',placeholder='keyname') }}
+ {{ form.keyname(class_='form-control',placeholder='username') }}
<p class="help-block">unique textual identifier - letters, numbers, dashes and underscores allowed - no spaces</p>
</div>
+ <div class="form-group">
+ *{{ form.user_email.label }}
+ {{ form.user_email(class_='form-control',placeholder='a@b.c') }}
+ </div>
+ <div class="form-group">
+ {{ form.password.label }}
+ {{ form.password(class_='form-control',placeholder='password') }}
+ </div>
+ <div class="form-group">
+ {{ form.password2.label }}
+ {{ form.password2(class_='form-control',placeholder='confirmation') }}
+ </div>
- Remove empty
password
from form to prevent update. - Remove
user_pass
from column list forroute/admin/user/list
.
user = UserModel.query.get_or_404(id)
form = EditUserForm(user)
if form.validate_on_submit():
+ if form.password.data == '':
+ del form.password
form.populate_obj(user)
db.session.add(user)
db.session.commit()
...
@user.route('/admin/user/view/<int:id>')
def user_view( id ):
- user = UserModel.query.get_or_404(id)
cols = UserModel.__table__.columns.keys()
+ user = UserModel.query.get_or_404(id)
return render_template('user_view.html', cols=cols, user=user)
...
@get_list_opts('user_list_opts')
def user_list():
cols = UserModel.__table__.columns.keys()
+ cols_filtered = list(filter(lambda x: x not in ['user_pass'], cols))
rows = db.session.query(UserModel)
...
- return render_template('user_list.html', cols=cols,rows=rows,rowcnt=rowcnt,opts_key=opts_key)
+ return render_template('user_list.html', cols=cols_filtered,rows=rows,rowcnt=rowcnt,opts_key=opts_key)
Commit-v0.22 | Commit-v0.23 | Commit-v0.24
- FlaskApp Tutorial
- Table of Contents
- About
- Application Setup
- Modules, Templates, and Layouts
- Database Items, Forms, and CRUD
- List Filter, Sort, and Paginate
- Users and Login
- Database Relationships
- API Module, HTTPAuth and JSON
- Refactoring User Roles and Item Status
- AJAX and Public Pages