美文网首页Flask 教程
23、Flask构建弹幕微电影网站-基于角色访问控制-管理员管理

23、Flask构建弹幕微电影网站-基于角色访问控制-管理员管理

作者: 攻城狮笔记 | 来源:发表于2019-04-13 15:47 被阅读8次

    百度云搜索,搜各种资料:http://www.81ad.cn

    Flask 构建微电影视频网站

    已上线演示地址: http://movie.tbquan.cn

    管理员管理

    管理员添加

    创建管理员表单

    通过表单的字段EqualTo()来验证重复密码是否一致。

    from wtforms.validators import DataRequired, ValidationError, EqualTo
    
    class AdminForm(FlaskForm):
        name = StringField(
            label='管理员名称',
            validators=[
                DataRequired('请输入管理员名称!')
            ],
            description='管理员名称',
            render_kw={
                'class': "form-control",
                'placeholder': "请输入管理员名称",
                'required': "required"
            }
        )
    
        pwd = PasswordField(
            label='管理员密码',
            validators=[
                DataRequired('请输入管理员密码!')
            ],
            description='管理员密码',
            render_kw={
                'class': "form-control",
                'placeholder': "请输入管理员密码",
                'required': "required"
            }
        )
        repwd = PasswordField(
            label='管理员重复密码',
            validators=[
                DataRequired('请输入管理员重复密码!'),
                EqualTo('pwd', message='两次密码不一致')
            ],
            description='管理员重复密码',
            render_kw={
                'class': "form-control",
                'placeholder': "请输入管理员重复密码",
                'required': "required"
            }
        )
        is_super = SelectField(
            label='星级',
            validators=[
                DataRequired('请选择星级!')
            ],
            description='星级',
            coerce=int,
            choices=[(1, '普通管理员'), (0, '超级管理员')],
            render_kw={
                'class': "form-control"
            }
        )
        role_id = SelectField(
            label='所属角色',
            validators=[
                DataRequired('请选择所属角色!')
            ],
            coerce=int,
            # choices=[(role.id, role.name) for role in Role.query.all()],
            description='所属角色',
            render_kw={
                'class': "form-control"
            }
        )
    
        def __init__(self, *args, **kwargs):
            super(AdminForm, self).__init__(*args, **kwargs)
            self.role_id.choices = [(v.id, v.name) for v in Role.query.all()]
    
        submit = SubmitField(
            label='提交',
            render_kw={
                'class': "btn btn-primary"
            }
        )
    
    

    修改admin_add管理员添加视图

    @admin.route("/admin/add/", methods=['GET', 'POST'])
    @admin_login_require
    def admin_add():
        form = AdminForm(is_super=1)
        from werkzeug.security import generate_password_hash
        print(form.data)
        if form.validate_on_submit():
            data = form.data
            if Admin.query.filter_by(name=data['name']).count() == 1:
                flash('管理员已存在!', category='err')
                return redirect(url_for('admin.admin_add'))
            add_admin = Admin(
                name=data['name'],
                pwd=generate_password_hash(data['pwd']),
                role_id=data['role_id'],
                is_super=1
            )
            db.session.add(add_admin)
            db.session.commit()
            flash('管理员添加成功', category='ok')
        return render_template('admin/admin_edit.html', form=form)
    
    

    修改admin_edit.html添加管理员模板

    <form role="form" method="post">
        {% include 'admin/alert_info.html' %}
        <div class="box-body">
            <div class="form-group">
                <label for="input_name">{{ form.name.label }}</label>
                {{ form.name }}
                {% for err in form.name.errors %}
                    <div class="col-md-12" style="color: red">{{ err }}</div>
                {% endfor %}
            </div>
            <div class="form-group">
                <label for="input_pwd">{{ form.pwd.label }}</label>
                {{ form.pwd }}
                {% for err in form.pwd.errors %}
                    <div class="col-md-12" style="color: red">{{ err }}</div>
                {% endfor %}
            </div>
            <div class="form-group">
                <label for="input_re_pwd">{{ form.repwd.label }}</label>
                {{ form.repwd }}
                {% for err in form.repwd.errors %}
                    <div class="col-md-12" style="color: red">{{ err }}</div>
                {% endfor %}
            </div>
            <div class="form-group">
                <label for="input_role_id">{{ form.role_id.label }}</label>
                {{ form.role_id }}
                {% for err in form.role_id.errors %}
                    <div class="col-md-12" style="color: red">{{ err }}</div>
                {% endfor %}
            </div>
        </div>
        {{ form.csrf_token }}
        <div class="box-footer">
            {{ form.submit }}
        </div>
    </form>
    
    
    BLOG_20181111_203446_93 BLOG_20181111_203451_13 BLOG_20181111_203510_94

    管理员列表

    修改admin_list管理员列表视图

    @admin.route("/admin/list/<int:page>")
    @admin_login_require
    def admin_list(page=None):
        if not page:
            page = 1
        page_admins = Admin.query.order_by(
            Admin.add_time.desc()
        ).join(
            Role
        ).filter(
            Role.id == Admin.role_id  # 关联查询
        ).paginate(page=page, per_page=10)
        return render_template('admin/admin_list.html', page_admins=page_admins)
    
    

    修改admin_list.html管理员列表模板

    <div class="box-body table-responsive no-padding">
        {% include 'admin/alert_info.html' %}
        <table class="table table-hover">
            <tbody>
            <tr>
                <th>编号</th>
                <th>管理员名称</th>
                <th>管理员类型</th>
                <th>管理员角色</th>
                <th>添加时间</th>
            </tr>
            {% for admin in page_admins.items %}
                <tr>
                    <td>{{ admin.id }}</td>
                    <td>{{ admin.name }}</td>
                    <td>{% if admin.is_super == 0 %}超级管理员{% else %}普通管理员{% endif %}</td>
                    <td>{{ admin.role.name }}</td>
                    <td>{{ admin.add_time }}1</td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
    </div>
    <div class="box-footer clearfix">
        {% import 'admin/pagination.html' as pg %}
        {{ pg.render_pagination(page_admins, 'admin.admin_list') }}
    </div>
    
    
    BLOG_20181111_203522_85

    访问权限控制

    在views.py中编写权限验证装饰器

    # 权限控制装饰器
    def permission_control(func):
        @wraps(func)
        def decorated_function(*args, **kwargs):
            login_admin = Admin.query.join(
                Role
            ) .filter(
                Role.id == Admin.role_id,
                Admin.name == session['login_admin']
            ).first()
    
            all_auth = Auth.query.all()  # 数据库所有权限
    
            auths = login_admin.role.auths
            auths = list(map(lambda item: int(item), auths.split(',')))  # 用户权限id列表
            urls = [auth.url for auth in all_auth for admin_auth_id in auths if admin_auth_id == auth.id]
    
            print(urls)
            rule = request.url_rule
            print(rule)  # 需要转为str判断是否在list中
            if str(rule) not in urls and login_admin.is_super != 0:  # 权限不存在,且不是超级管理员
                abort(401)
            return func(*args, **kwargs)
        return decorated_function
    
    

    在各个视图中添加装饰

    例如:

    @admin.route("/")
    @admin_login_require
    @permission_control
    def index():
        # ....
    
    @admin.route("/tag/add/", methods=['GET', 'POST'])
    @admin_login_require
    @permission_control
    def tag_add():
        # ....
    
    

    创建无权访问提示

    创建401视图

    app/__init__.py中添加以下视图和404的视图在一个文件中

    # 添加全局401无权限页面
    @app.errorhandler(401)
    def unauthorized_access(error):
        return render_template('401.html'), 401
    
    

    创建401模板

    这儿就没什么样式,随意了

    {% extends 'admin/base.html' %}
    
    {% block content %}
    <h1>无权访问<a href="{{ request.path }}">{{ request.path }}</a> </h1>
    {% endblock %}
    
    

    当访问无权限的url时,会进行提示

    BLOG_20181111_203544_27

    相关文章

      网友评论

        本文标题:23、Flask构建弹幕微电影网站-基于角色访问控制-管理员管理

        本文链接:https://www.haomeiwen.com/subject/nyxrwqtx.html