Flask web平台开发实战(2)-用户登录页面搭建及登录退出
2019-07-22 本文已影响0人
金鱼座
大家好,我是金鱼座,一个走在测试领域这片蓝海中, 蹉跎前行的技术渣渣,唯有一直走下去,也许能改变点什么,加油!
前一天主要完成了项目的基本框架搭建, 本次主要来完成登录页面的完善和登录退出功能的开发
1. 登录页面
登录页面主要从adminlte中的获取登录页面模板,该模板主要基于bootstrap搭建,如下图
image.png2. 数据库表生成
在table目录的db_.py文件中, 进行当前工作的开发数据表任务,当前登录用户主要涉及到三个表,User表,Auth表,Role表
from datetime import datetime
from app import db
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 编号
name = db.Column(db.String(100), unique=True) # 管理员账号
pwd = db.Column(db.String(100)) # 管理员密码
role_id = db.Column(db.Integer) # 所属角色
addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间
def __repr__(self):
return "<User %r>" % self.name
# def check_pwd(self, pwd):
# from werkzeug.security import check_password_hash
# # print(check_password_hash(self.pwd, pwd))
# return check_password_hash(self.pwd, pwd)
# 角色表
class Role(db.Model):
__tablename__ = "role"
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 编号
name = db.Column(db.String(100), unique=True) # 名称
auths = db.Column(db.String(600)) # 角色权限列表
addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间
def __repr__(self):
return "<Role %r>" % self.name
# 权限表
class Auth(db.Model):
__tablename__ = "auth"
id = db.Column(db.Integer, primary_key=True) # 编号
name = db.Column(db.String(100), unique=True) # 名称
url = db.Column(db.String(255), unique=True) # 地址
addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间
def __repr__(self):
return "<Auth %r>" % self.name
表生成:
进入虚拟环境的manage.py 目录下,分别执行
> python3 manage.py db init * 初始化db,生成 migrations文件夹
> python3 manage.py db migrat*e 数据检查变化,生成执行py
> python3 manage.py db upgrade 数据执行,执行后,数据表变化更新
3. 蓝图注册
注册对应的url
image4. form表单验证
使用wtform模块,在forms.py文件中,构建表单项以及对于的验证
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, FileField, TextAreaField, SelectField
from wtforms.validators import DataRequired, ValidationError
from table.db_ import User
#
class LoginForm(FlaskForm):
name = StringField(label="账号",
validators=[DataRequired("请输入账号1")],
description="账号1",
render_kw={
'class': "form-control",
'placeholder': "请输入账号!",
'type': "user"
# 'required': "required"
})
pwd = PasswordField(label="密码",
validators=[DataRequired("请输入密码1")],
description="密码1",
render_kw={
'class': "form-control",
'placeholder': "请输入密码!",
'type': "pwd"
# 'required': "required"
})
submit = SubmitField(
label='登录',
description="登录按钮",
render_kw={
'class': "btn btn-primary btn-block btn-flat",
}
)
# 自定义字段验证
def validate_name(self, field):
user = field.data
admin = User.query.filter_by(name=user).count()
if admin == 0:
raise ValidationError("账号不存在")
5. 视图函数实现业务逻辑
# 登录功能
@home.route("/login", methods=["GET", "POST"])
def login():
form = LoginForm()
if form.validate_on_submit():
data = form.data
user = User.query.filter_by(name=data["name"]).first()
if user.pwd != data["pwd"]:
flash("密码错误!", "err")
return redirect(url_for("home.login"))
session["user"] = user.name
session["user_id"] = user.id
return redirect(url_for("admin.admin"))
return render_template("home/login.html", form=form)
# 退出功能
@home.route("/logout", methods=["GET"])
def logout():
session.pop('user', None)
session.pop('user_id', None)
return redirect(url_for("home.login"))
# 访问是否登录装饰器
def is_login(fun):
@wraps(fun)
def decorated_function(*args, **kwargs):
# if "user" not in session:
if not session.get('user'):
return redirect(url_for("home.login", next=request.url))
return fun(*args, **kwargs)
return decorated_function
6. 前台form表单的改写
# form表单
<form action="/login" role="form" method="POST">
<div class="form-group has-feedback">
{{ form.name }}
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
{{ form.pwd }}
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-8">
<div class="checkbox icheck">
<label>
<input type="checkbox"> 记住密码
</label>
</div>
</div>
<!-- /.col -->
<div class="col-xs-4">
{# <button type="submit" class="btn btn-primary btn-block btn-flat">登录</button>#}
{{ form.submit }}
{{ form.csrf_token }} # form表单提交一定要有这个crsftoken
</div>
<!-- /.col -->
</div>
</form>
注意事项:
form标签中,action为空时, 默认会使用当前的url来发送post请求
form表单提交内容中,最后在提交的地方可以加上csrftoken的验证,