zoukankan      html  css  js  c++  java
  • 权限分配实现思路

    先上一张,效果图。 OK
    开始做:
    用户信息  和 角色。很容易就能搞成。 只需要从数据库取出。 menu  和 role 两张表的全部数据, 再模板进行循环的渲染就行了。

        all_user_queryset = models.UserInfo.objects.all()
        all_role_queryset = models.Role.objects.all()
    

     拿到数据,前端直接渲染就好了!

    {% extends "layout.html" %}
    {% block css %}
        <style type="text/css">
            tr.active {
                border-left: #eea236 solid 2px;
            }
        </style>
    {% endblock %}
    {% load rbac_tags %}
    {% block content %}
        <div class="luffy-container">
            <div class="col-md-3">
                <div class="panel panel-default">
                    <!-- Default panel contents -->
                    <div class="panel-heading"><i class="fa fa-book" aria-hidden="true"></i>员工信息</div>
                    <div class="panel panel-body">
                        <ul>
                            {% for user in all_user_list %}
                                <li><a href="">{{ user.name }}</a></li>
                            {% endfor %}
                        </ul>
                    </div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="panel panel-default">
                    <div class="panel-heading"><i class="fa fa-binoculars" aria-hidden="true"></i>角色信息</div>
                    <div class="panel panel-body">
                    提示:点击用户后才能为其分配角色
                        <table class="table table-condensed">
                            <thead>
                            <tr>
                                <th>角色</th>
                                <th>选项</th>
                            </tr>
                            </thead>
                            <tbody>
                            {% for role in all_role_list %}
                                <tr>
                                    <td><a href="">{{role.title}}</a></td>
                                    <td><input type="checkbox" name="roles" value="{{ role.id }}"></td>
                                </tr>
                            {% endfor %}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    {% endblock %}
    这部分,我也没搞 样式!  看自己心情!

    最后的  权限分配这里,才是重点:
      可以看到的是, 这有一个层级结构。  业务管理 为一级菜单。 账单列表为二级菜单。 其余的就是 各属于二级菜单之下的 权限。
    所以如果 在模板进行渲染的时候, 是一个 列表嵌套字典的格式,会容易许多:
      比如这样的:

    {
        'mid': 1,
        'title': '用户管理',
        'children': [{
            'id': 1,
            'title': '客户列表',
            'menu_id': 1,
            'children': [{
                'id': 2,
                'title': '添加客户',
                'pid_id': 1
            }, {
                'id': 3,
                'title': '修改客户',
                'pid_id': 1
            }, {
                'id': 4,
                'title': '删除客户',
                'pid_id': 1
            }, {
                'id': 5,
                'title': '批量导入',
                'pid_id': 1
            }, {
                'id': 6,
                'title': '下载模板',
                'pid_id': 1
            }]
        }]
    }

     这样子中三层的,层级结构。  传给模板的时候,就只需要。 三层循环就可以了!
          如果你想递归, 我也有 递归的方法。(一个用于渲染评论树的代码)
    第一步也是没啥好所的, 先从数据库把 所有的数据取出来:

        # 所有的一级菜单
        all_menu_queryset = models.Menu.objects.values("mid", "title")
        # 所有的二级菜单
        all_second_menu_queryset = models.Permission.objects.filter(menu_id__isnull=False).values("id", "title", "menu_id")
        # 所有的不是二级菜单的权限
        all_permission_queryset = models.Permission.objects.filter(menu_id__isnull=True).values("id", "title", "pid_id")

    这里有一点 必须要说明:  Python 的赋值是使用的, 引用机制。 所以才会有下面方法的, 构造数据的方式:
    这里可能会有疑惑,为什么更新的是字典。 但是最后用的却是最初循环的列表呢?

        all_menu_dict = {}  # 只是为了,在循环中查找数据方便,创建的字典
        for item in all_menu_queryset:
            item["children"] = []
            all_menu_dict[item.get("mid")] = item
    # 我这里在循环的时候, 给all_menu_queryset中每一个item(这是一个字典)添加了一个 ["children"] = []。 
    注意!!!! 我是先添加了一个键值对, 才保存到all_menu_dict字典中的。 所以当我下面的循环,在对这个字典中的 ["children"] = [] 这个列表进行添加操作
    的时候。 改变的不仅仅是 我这个字典的数据。 会连带着all_menu_queryset中的数据,也会发生变化! 因为python 的引用机制。 大家使用的都是同一块内存地址

    all_second_menu_dict
    = {} for row in all_second_menu_queryset: row["children"] = [] all_second_menu_dict[row.get("id")] = row menu_id = row.get("menu_id") # 如果没数据库没有做关联的话, 这里要判断以下 是否有这个 menu_id all_menu_dict.get(menu_id).get("children").append(row) # 因为我的数据库是做了关联的,所以才能在这里直接查找赋值。 for row in all_permission_queryset: pid_id = row.get("pid_id") if not pid_id: continue all_second_menu_dict.get(pid_id).get("children").append(row)

    queryset 是一种类似于, 列表的结构。  最终所有的数据, 都保存在了 all_menu_queryset 这个里面。

    然后就是, 所有判断,当前用户是谁。 让权限表,角色表。  让相应的 checkbox 带上 checked 属性。 这里就需要让后台知道当前用户点击的

    还是 老套路。 在用户和角色的的 标签上!加上 ?uid=1  和 ?uid=1&rid=1。 如果忘了,就去前面的博客复习。
    https://www.cnblogs.com/chengege/p/10710371.html

    然后是,视图部分代码逻辑:

        user_id = request.GET.get('uid')
        role_id = request.GET.get('rid')
        user_obj = models.UserInfo.objects.filter(pk=user_id).first()
        role_obj = models.Role.objects.filter(pk=role_id).first()
    
        if not user_obj:
            user_id = None
    
        if not role_obj:
            role_id = None
    
        # 获取当前用户所拥有的角色. 进行默认选择
        if user_id:
            user_has_role = user_obj.roles.all().values("id")
        else:
            user_has_role = []
        user_has_role_dict = {item["id"]: None for item in user_has_role}
    
        # 如果选中了角色,优先显示选中的角色,拥有的权限。 如果没有选择角色,才显示用户的所有权限
        if role_obj:
            user_has_permissions = role_obj.permissions.all()
            user_has_permissions_dict = {item.id: None for item in user_has_permissions}
        elif user_obj:
            user_has_permissions = user_obj.roles.values("permissions__id").distinct()  # 获取当前用户所拥有的所有权限
            user_has_permissions_dict = {item["permissions__id"]: None for item in user_has_permissions}
        else:
            user_has_permissions_dict = {}
    View Code

    前端使用同一个,user_has_permissions_dict 。在后台 进行判断。  如果用户选中了角色,优先显示选中的角色,拥有的权限。 如果没有选择角色,才显示用户的所有权限。
    最后是,提交保存的代码:

        if request.method == "POST" and request.POST.get("type") == "role":
            role_id_list = request.POST.getlist("roles")
            if not user_obj:
                return HttpResponse("请选择用户,不要自己添加input标签。烦得很")
            user_obj.roles.set(role_id_list)  # 通过用户找到 roles 然后set 向他们的关系表。 更新数据
        if request.method == "POST" and request.POST.get("type") == "permission":
            permission_id_list = request.POST.getlist("permissions")
            if not user_obj or not role_obj:
                return HttpResponse("请选择用户,不要自己添加input标签。烦得很")
            role_obj.permissions.set(permission_id_list)
    View Code

    这里用到了, ORM 中。 对多对多关系表,更新的 set() 方法。

    头昏脑涨:太晚了!先放上所有代码:

    def distribute_permission(request):
        '''
        权限分配
        :param request:
        :return:
        '''
        user_id = request.GET.get('uid')
        role_id = request.GET.get('rid')
        user_obj = models.UserInfo.objects.filter(pk=user_id).first()
        role_obj = models.Role.objects.filter(pk=role_id).first()
    
    
        if request.method == "POST" and request.POST.get("type") == "role":
            role_id_list = request.POST.getlist("roles")
            if not user_obj:
                return HttpResponse("请选择用户,不要自己添加input标签。烦得很")
            user_obj.roles.set(role_id_list)  # 通过用户找到 roles 然后set 向他们的关系表。 更新数据
        if request.method == "POST" and request.POST.get("type") == "permission":
            permission_id_list = request.POST.getlist("permissions")
            if not user_obj or not role_obj:
                return HttpResponse("请选择用户,不要自己添加input标签。烦得很")
            role_obj.permissions.set(permission_id_list)
    
        if not user_obj:
            user_id = None
    
        if not role_obj:
            role_id = None
    
        # 获取当前用户所拥有的角色. 进行默认选择
        if user_id:
            user_has_role = user_obj.roles.all().values("id")
        else:
            user_has_role = []
        user_has_role_dict = {item["id"]: None for item in user_has_role}
    
        # 如果选中了角色,优先显示选中的角色,拥有的权限。 如果没有选择角色,才显示用户的所有权限
        if role_obj:
            user_has_permissions = role_obj.permissions.all()
            user_has_permissions_dict = {item.id: None for item in user_has_permissions}
        elif user_obj:
            user_has_permissions = user_obj.roles.values("permissions__id").distinct()  # 获取当前用户所拥有的所有权限
            user_has_permissions_dict = {item["permissions__id"]: None for item in user_has_permissions}
        else:
            user_has_permissions_dict = {}
    
        all_user_queryset = models.UserInfo.objects.all()
        all_role_queryset = models.Role.objects.all()
    
        # 所有的一级菜单
        all_menu_list = models.Menu.objects.values("mid", "title")
        # 所有的二级菜单
        all_second_menu_queryset = models.Permission.objects.filter(menu_id__isnull=False).values("id", "title", "menu_id")
        # 所有的不是二级菜单的权限
        all_permission_queryset = models.Permission.objects.filter(menu_id__isnull=True).values("id", "title", "pid_id")
    
        all_menu_dict = {}
        for item in all_menu_list:
            item["children"] = []
            all_menu_dict[item.get("mid")] = item
    
        all_second_menu_dict = {}
        for row in all_second_menu_queryset:
            row["children"] = []
            all_second_menu_dict[row.get("id")] = row
    
            menu_id = row.get("menu_id")
            all_menu_dict.get(menu_id).get("children").append(row)
    
        for row in all_permission_queryset:
            pid_id = row.get("pid_id")
            if not pid_id:
                continue
            all_second_menu_dict.get(pid_id).get("children").append(row)
    
        return render(request, "rbac/distribute_permissions.html",
                      {"all_user_list": all_user_queryset,
                       "all_role_list": all_role_queryset,
                       "all_menu_queryset": all_menu_list,
                       "user_id": user_id,
                       "role_id": role_id,
                       "user_has_role_dict": user_has_role_dict,
                       "user_has_permissions_dict": user_has_permissions_dict})
    试图函数
    {% extends "layout.html" %}
    {% block css %}
        <style>
            table {
                font-size: 12px;
            }
            .panel-body{font-size: 12px;margin-bottom: 0}
    
            .user-area ul {
                padding-left: 20px;
            }
    
            .user-area li {
                cursor: pointer;
                padding: 2px 0;
            }
    
            .user-area li a {
                display: block;
            }
    
            .user-area li.active {
                font-weight: bold;
                color: red;
            }
    
            .user-area li.active a {
                color: red;
            }
    
            .role-area tr td a {
                display: block;
            }
    
            .role-area tr.active {
                background-color: #f1f7fd;
                border-left: 3px solid #fdc00f;
            }
    
            .panel-body {
                font-size: 12px;
            }
    
            .permission-area tr.root {
                background-color: #f1f7fd;
            }
    
            .permission-area tr.root td i {
                margin: 3px;
            }
    
            .permission-area .node {
            }
    
            .permission-area .node input[type='checkbox'] {
                margin: 0 5px;
            }
    
            .permission-area .node .parent {
                padding: 5px 0;
            }
    
            .permission-area .node label {
                font-weight: normal;
                margin-bottom: 0;
                font-size: 12px;
            }
    
            .permission-area .node .children {
                padding: 0 0 0 20px;
            }
    
            .permission-area .node .children .child {
                display: inline-block;
                margin: 2px 5px;
            }
    
            .select-help {
                float: right;
            }
    
            .select-help label {
                font-weight: normal;
                cursor: pointer;
            }
    
            .select-help .check-all {
                float: left;
                display: inline-block;
                margin-right: 8px;
            }
        </style>
    {% endblock %}
    {% load rbac_tags %}
    {% block content %}
        <div class="luffy-container">
            <div class="col-md-3 user-area">
                <div class="panel panel-default">
                    <!-- Default panel contents -->
                    <div class="panel-heading"><i class="fa fa-book" aria-hidden="true"></i>员工信息</div>
                    <div class="panel panel-body">
                        <ul>
                            {% for user in all_user_list %}
                                <li class="{% if user_id == user.id|safe %}active{% endif %}">
                                    <a href="?uid={{ user.id }}">{{ user.name }}</a></li>
                            {% endfor %}
                        </ul>
                    </div>
                </div>
            </div>
    
    
            <div class="col-md-3 role-area">
                <div class="panel panel-default">
                    <form method="post">
                        {% csrf_token %}
                        <input type="hidden" name="type" value="role">
                        <div class="panel-heading"><i class="fa fa-binoculars" aria-hidden="true">角色信息</i>
                            {% if user_id %}
                                <button type="submit" class="right btn btn-success btn-xs"
                                        style="padding: 2px 8px;margin: -3px;">
                                    <i class="fa fa-save" aria-hidden="true"> 保存</i>
                                </button>
                            {% endif %}
                        </div>
                        <div class="panel panel-body" style="color: #737373">
                            提示:点击用户后才能为其分配角色
                        </div>
                        <table class="table table-condensed">
                            <thead>
                            <tr>
                                <th>角色</th>
                                <th>选项</th>
                            </tr>
                            </thead>
                            <tbody>
                            {% for role in all_role_list %}
                                <tr class="{% if role.id|safe == role_id %}active{% endif %}">
                                    <td>
                                        {% if user_id %}
                                            <a href="?uid={{ user_id }}&rid={{ role.id }}">{{ role.title }}</a>
                                        {% else %}
                                            <a href="?rid={{ role.id }}">{{ role.title }}</a>
                                        {% endif %}
                                    </td>
                                    <td>
                                        <input {% if role.id     in user_has_role_dict %}checked{% endif %}
                                               type="checkbox" name="roles" value="{{ role.id }}">
                                    </td>
                                </tr>
                            {% endfor %}
                            </tbody>
                        </table>
                    </form>
                </div>
            </div>
    
    
            <div class="col-md-6 permission-area">
                <div class="panel panel-default">
                    <form method="post">
                        {% csrf_token %}
                        <input type="hidden" name="type" value="permission">
                        <div class="panel-heading"><i class="fa fa-binoculars" aria-hidden="true">权限分配</i>
                            {% if role_id %}
                                <button type="submit" class="right btn btn-success btn-xs"
                                        style="padding: 2px 8px;margin: -3px;">
                                    <i class="fa fa-save" aria-hidden="true"> 保存</i>
                                </button>
                            {% endif %}
                        </div>
                        <div class="panel panel-body">
                            提示:必须要选择角色,才可以分配权限
                        </div>
                        <table class="table">
                            <tbody>
                            {% for item in all_menu_queryset %}
                                <tr class="root">
                                    <td>
                                        <i class="fa fa-caret-down" aria-hidden="true"></i>
                                        {{ item.title }}
                                        <div class="select-help">
                                            <div class="check-all">
                                                <label for="check_all_{{ item.mid }}">全选</label>
                                                <input id="check_all_{{ item.mid }}" type="checkbox">
                                            </div>
                                        </div>
                                    </td>
                                </tr>
                                {% if item.children %}
                                    <tr class="node">
                                        <td>
                                            {% for node in item.children %}
                                                <div class="parent">
                                                    <input id="permission_{{ node.id }}" name="permissions"
                                                           {% if node.id in user_has_permissions_dict %}checked{% endif %}
                                                           value="{{ node.id }}" type="checkbox">
                                                    <label for="permission_{{ node.id }}">{{ node.title }}(菜单)</label>
                                                </div>
                                                <div class="children">
                                                    {% for child in node.children %}
                                                        <div class="child">
    
                                                            <input id="permission_{{ child.id }}" name="permissions"
                                                                   {% if child.id in user_has_permissions_dict %}checked{% endif %}
                                                                   type="checkbox" value="{{ child.id }}">
    
                                                            <label for="permission_{{ child.id }}">{{ child.title }}</label>
                                                        </div>
                                                    {% endfor %}
                                                </div>
                                            {% endfor %}
                                        </td>
                                    </tr>
                                {% endif %}
                            {% endfor %}
                            </tbody>
                        </table>
                    </form>
                </div>
            </div>
        </div>
    {% endblock %}
    
    {% block js %}
        <script type="text/javascript">
        $(function () {
            $(".check-all input:checkbox").change(function () {
                $(this).parents(".root").next().find("input:checkbox").prop("checked", $(this).prop("checked"));
            })
        })
        </script>
    {% endblock %}
    templates
  • 相关阅读:
    hihoCoder#1040 矩形判断
    hihoCoder#1038 01背包
    hihoCoder#1037 数字三角形
    hihoCoder#1120 小Hi小Ho的惊天大作战:扫雷·三
    hihoCoder#1119 小Hi小Ho的惊天大作战:扫雷·二
    Python核心编程读笔 3
    Python核心编程读笔 2
    EC读书笔记系列之12:条款22、23、24
    Linux程序设计 读笔2 Shell脚本
    Linux程序设计 读笔1
  • 原文地址:https://www.cnblogs.com/chengege/p/10727213.html
Copyright © 2011-2022 走看看