day24-基于rbac的crm

今日内容:不同用户分权限(展示不同的菜单)
内容回顾:
settings的配置文件中的key都是大写
内容回顾:
    1.使用别人源码,启动:解释器+工作目录
    
    2. django请求生命周期
    
    3. 配置文件
        - key必须大写
        - 导入配置
            from django.conf import settings
    
    3. 在模板中定义函数
        - sample_tag
        - inclusion_tag
    
    4. 寻找模板的顺序(静态文件)
        - 最外层templates目录 (static- 去注册的app下的templates目录中找(按照app注册顺序)(static5. auto示例:所有用户登录后看到的菜单都一样。
回顾

今日内容:
1.回顾用户、角色、权限表的创建
2.设计含菜单的最终表结构:在权限表中加menu_id,(is_menu),pid
数据库设计
            from django.db import models

            class Menu(models.Model):
                """
                菜单表
                """
                title = models.CharField(verbose_name='标题',max_length=32)
                icon = models.CharField(verbose_name='图标',max_length=32)


            class Permission(models.Model):
                """
                权限表
                """
                url = models.CharField(verbose_name='URL(含正则)', max_length=128)
                title = models.CharField(verbose_name='名称',max_length=32)
                name = models.CharField(verbose_name='别名',max_length=32,unique=True)

                menu = models.ForeignKey(verbose_name='管理菜单',to='Menu',to_field='id',null=True,blank=True)
                parent = models.ForeignKey(verbose_name='父菜单',to='Permission',null=True,blank=True)
                
                
            class Role(models.Model):
                """
                角色表
                """
                title = models.CharField(verbose_name='名称', max_length=32)
                permissions = models.ManyToManyField(verbose_name='关联权限',to='Permission')
                
                
            class UserInfo(models.Model):
                """
                用户表
                """
                username = models.CharField(verbose_name='用户名',max_length=32)
                password = models.CharField(verbose_name='密码',max_length=64)
                roles = models.ManyToManyField(verbose_name='关联角色',to='Role')
    
数据库设计

给url取别名,且别名不能重复
创建表时类别首字母大写
1对多时,将外键关联的字段写在多的表中;多对多时,写在常用查询的位置
3.写model中代码,数据填充
4.去掉web相关内容
上一节功能去掉
            - 去掉web app
            - url.py
                urlpatterns = [
                    url(r'^admin/', admin.site.urls),
                    # url(r'^web/', include('web.urls')),
                ]
            - settings.py 
                去掉 MENU_LIST
                去掉注册的app:    'web.apps.WebConfig',
View Code

5.取数据(权限和菜单信息)
可以连续跨表
获取权限信息,获取可以做菜单的权限信息

6.复制service文件夹,完成权限初始化
复制中间件中权限 可以去写好的中间件中参考引入
注册中间件 设置默认选中菜单

权限控制

7.动态生成二级菜单
注意menu.html中去掉if is_menu判断

模板:权限校验rbac+菜单menu+模板样式

8.用户列表显示
如果没有权限,按钮不展示
---粒度控制到按钮级别(要有别名name)
自定义filter函数(因为在模板语言中不能用inclusion_tag)
注意使用:{% if 'xxx'|permission:request %} {% endif %}
操作、表格业没有也加if即可

9.应用-使用权限系统
通过别名反向生成url

共9步
1. 拷贝rbac应用
        
        2. 删除rbac/migrations目录中除 __init__.py 以外的所有文件
        
        3. 配置文件中注册 rbac的app
            INSTALLED_APPS = [
                ...
                'rbac.apps.RbacConfig',
            ]
        
        4. 数据库迁移 
            python manage.py makemigrations
            python manage.py migrate
            
        
        5. 编写测试系统的业务逻辑
            如果使用rbac中的模板的话,需要先删除layout.html中的:
                 <!-- 导入xxxxxxx模块 -->
                {% load rbac %}
                <!-- 执行get_menu函数并传递了一个参数 -->
                {% get_menu request %}
        
            业务逻辑开发完毕....
    
        6. 设置权限相关的配置文件
            # ############################ 权限+菜单相关配置 #############################
            RBAC_PERMISSION_SESSION_KEY = "ijksdufwesdfs"
            RBAC_MENU_SESSION_KEY = "rtwsdfgwerffsd"

            VALID_LIST = [
                '/api/login/',
                '/admin/.*'
            ]
            
        7. 基于django admin 录入权限数据
            - 菜单 
            - 权限 
            - 权限角色关系表
            - 角色 
            - 用户角色关系表
            - 用户 
            
        8. 权限和菜单信息的应用
            - 用户登录:初始化权限和菜单信息
                def login(request):
                    """
                    用户登录
                    :param request:
                    :return:
                    """
                    if request.method == "GET":
                        return render(request, 'api/login.html')
                    
                    user = request.POST.get('user')
                    pwd = request.POST.get('pwd')
                    
                    user = rbac_model.UserInfo.objects.filter(username=user, password=pwd).first()
                    if not user:
                        return render(request, 'api/login.html', {'msg': '用户名或密码错误'})
                    # ############ 看这里 ############
                    init_permission(user, request)
                    
                    return redirect('/api/app/list/')
            - 中间件:权限判断
                settings.py 
                    MIDDLEWARE = [
                        ...
                        'rbac.middlewares.rbac.RBACMiddleware',
                    ]
            - inclusion_tag:动态生成菜单 
                layout.html 
                    <div class="menu-body">
                        {% load rbac %}

                        {% get_menu request %}
                    </div>
                        
            
        9. 控制页面按钮
            
            {% extends 'layout.html' %}
            
            {% load rbac %} 

            {% block content %}
                <h1>应用列表</h1>
                
                {% if 'app_add'|permission:request %}
                    <a class="btn btn-primary" href="{% url 'app_add' %}">添加</a>
                {% endif %}
                
                <table class="table table-bordered">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>姓名</th>
                             {% if "app_edit"|permission:request or "app_del"|permission:request %}
                            <th>操作</th>
                            {% endif %}
                        </tr>
                    </thead>
                    <tbody>
                        {% for row in app_queryset %}
                            <tr>
                                <td>{{ row.id }}</td>
                                <td>{{ row.title }}</td>
                                {% if "app_edit"|permission:request or "app_del"|permission:request %}
                                <td>
                                    {% if "app_edit"|permission:request %}
                                        <a href="{% url 'app_edit' row.id %}">编辑</a>
                                    {% endif %}
                                    {% if "app_del"|permission:request %}
                                        <a href="{% url 'app_del' row.id %}/">删除</a>
                                    {% endif %}
                                </td>
                                {% endif %}
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>


            {% endblock %}
            
步骤

权限和菜单的应用,按钮的控制引用filter

小结-------
权限可以被应用到任何一个系统
总结:
    1. 保存的代码:
        - 上一节示例:auto - 7 - 静态的菜单示例(最终版).zip 
        - 本节示例:nb_test.zip 
        
    2. 权限相关--记住
        
        1. 权限系统是如何实现的?
            基于角色的权限控制(rbac)
            
        2. 权限系统中用了哪些表?表中都有哪些字段?
        --见上面
    
        3. 你用中间件实现过什么?为什么使用中间件?
            rbac对权限的控制。
            所有的请求都会走中间件,所以权限控制在中间件中。
        4. 你认为哪里最难搞?
            - 动态二级菜单+默认选中
            - 构建菜单和权限的数据结构时。
            
        5. 其他
            ...
    流程总结:用户登录--将权限和菜单放入session中(定义一个init_permission),通过中间件进行权限的判断。通过inclusion_tag:动态生成菜单
控制页面按钮用filter实现
wsgi,中间件--描述清楚
初始化--中间件--inlcusiontag 三块代码

猜你喜欢

转载自www.cnblogs.com/lijie123/p/9839888.html