Flask web平台开发实战(2)-用户登录页面搭建及登录退出

2019-07-22  本文已影响0人  金鱼座

大家好,我是金鱼座,一个走在测试领域这片蓝海中, 蹉跎前行的技术渣渣,唯有一直走下去,也许能改变点什么,加油!

前一天主要完成了项目的基本框架搭建, 本次主要来完成登录页面的完善和登录退出功能的开发

1. 登录页面

登录页面主要从adminlte中的获取登录页面模板,该模板主要基于bootstrap搭建,如下图

image.png

2. 数据库表生成

在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

image

4. 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的验证,

上一篇下一篇

猜你喜欢

热点阅读