• rbac组件权限分配之权限展示


    示例效果:

     

     

     

     功能讲解:

      权限的新建按钮,只有点击二级菜单后才会显示;添加新的权限,默认为所点击的二级菜单进行添加新的权限,可以看到在前端的添加页面没有pid这个字段,在后端代码中已经设置了pid的值;

    rbac/urls.py

    from django.urls import re_path
    from rbac.views import role
    from rbac.views import user
    from rbac.views import menu
    
    urlpatterns = [
        # 角色管理
        re_path(r'^role/list/$', role.role_list, name="role_list"),
        re_path(r'^role/add/$', role.role_add, name="role_add"),
        re_path(r'^role/edit/(?P<pk>\d+)/$', role.role_edit, name="role_edit"),
        re_path(r'^role/del/(?P<pk>\d+)/$', role.role_del, name="role_del"),
        # 用户管理
        re_path(r'^user/list/$', user.user_list, name="user_list"),
        re_path(r'^user/add/$', user.user_add, name="user_add"),
        re_path(r'^user/edit/(?P<pk>\d+)/$', user.user_edit, name="user_edit"),
        re_path(r'^user/del/(?P<pk>\d+)/$', user.user_del, name="user_del"),
        re_path(r'^user/reset/password/(?P<pk>\d+)/$', user.user_reset_pwd, name="user_reset_pwd"),
        # 一级菜单管理
        re_path(r'^menu/list/$', menu.menu_list, name="menu_list"),
        re_path(r'^menu/add/$', menu.menu_add, name="menu_add"),
        re_path(r'^menu/edit/(?P<pk>\d+)/$', menu.menu_edit, name="menu_edit"),
        re_path(r'^menu/del/(?P<pk>\d+)/$', menu.menu_del, name="menu_del"),
        # 二级菜单管理
        re_path(r'^second/menu/add/(?P<menu_id>\d+)/$', menu.second_menu_add, name="second_menu_add"),
        re_path(r'^second/menu/edit/(?P<pk>\d+)/$', menu.second_menu_edit, name="second_menu_edit"),
        re_path(r'^second/menu/del/(?P<pk>\d+)/$', menu.second_menu_del, name="second_menu_del"),
        # 权限展示
        re_path(r'^permissions/add/(?P<second_menu_id>\d+)/$', menu.permission_add, name="permission_add"),
        re_path(r'^permissions/edit/(?P<pk>\d+)/$', menu.permission_edit, name="permission_edit"),
        re_path(r'^permissions/del/(?P<pk>\d+)/$', menu.permission_del, name="permission_del"),
    ]

    rbac/views/menu.py

    from django.shortcuts import render, redirect, HttpResponse
    from rbac import models
    from rbac.forms.menu import MenuModelForm, SecondMenuModelForm, PermissionModelForm
    from rbac.service.urls import memory_reverse
    
    
    def menu_list(request):
        """
        菜单和权限列表
        :param request:
        :return:
        """
        menus = models.Menu.objects.all().order_by("pk")
        # menu_list.html的菜单名称是a标签,此a标签的href在当前url后面加了mid参数
        # 取到该参数后,传给模板,模板与所循环一级菜单的id进行if比较,如果相等,那么加上'active'表示选中
        menu_id = request.GET.get("mid")  # 用户选择的一级菜单
        second_menu_id = request.GET.get("sid")  # 用户选择的二级菜单
        # 如果一级菜单的id不存在,那么将menu_id设置为None,menu_id控制二级菜单的'新建'按钮
        if not models.Menu.objects.filter(id=menu_id).exists():
            menu_id = None
        # 如果二级菜单id不存在,那么就将其设置为None,控制权限新建按钮的显示
        if not models.Permission.objects.filter(id=second_menu_id).exists():
            second_menu_id = None
        # 如果一级菜单id存在,那么将二级菜单的数据信息查询出来传给模板;如果一级菜单id为空,查询到的数据
        # 是不能作为二级菜单的url,所以还需要做一个判断,即一级菜单为空时,二级菜单数据信息为一个空列表
        # 那么二级菜单展示也是为空
        if menu_id:
            second_menus = models.Permission.objects.filter(menu_id=menu_id)  # 根据一级菜单的id查询二级菜单
        else:
            second_menus = []
        # 查询出不能做二级菜单的URL
        if second_menu_id:
            permissions = models.Permission.objects.filter(pid_id=second_menu_id)
        else:
            permissions = []
        return render(
            request,
            "rbac/menu_list.html",
            {
                "menus": menus,
                "mid": menu_id,
                "second_menus": second_menus,
                "sid": second_menu_id,
                "permissions": permissions,
            }
        )
    
    
    def permission_add(request, second_menu_id):
        """
        添加权限
        :param request:
        :param second_menu_id:
        :return:
        """
        if request.method == "GET":
            form = PermissionModelForm()
            return render(request, "rbac/change.html", {"form": form})
        form = PermissionModelForm(data=request.POST)
        if form.is_valid():
            second_menu_object = models.Permission.objects.filter(id=second_menu_id).first()
            if not second_menu_object:
                return HttpResponse("二级菜单不存在,请重新选择...")
            form.instance.pid = second_menu_object  # 给pid字段设置一个值
            form.save()
            return redirect(memory_reverse(request, "rbac:menu_list"))
        return render(request, "rbac/change.html", {"form": form})
    
    
    def permission_edit(request, pk):
        """
        编辑权限
        :param request:
        :param pk:
        :return:
        """
        obj = models.Permission.objects.filter(id=pk).first()
        if not obj:
            return HttpResponse("权限不存在...")
        if request.method == "GET":
            form = PermissionModelForm(instance=obj)
            return render(request, "rbac/change.html", {"form": form})
        form = PermissionModelForm(instance=obj, data=request.POST)
        if form.is_valid():
            form.save()
            return redirect(memory_reverse(request, "rbac:menu_list"))
        return render(request, "rbac/change.html", {"form": form})
    
    
    def permission_del(request, pk):
        """
        删除权限
        :param request:
        :param pk:
        :return:
        """
        url = memory_reverse(request, "rbac:menu_list")
        if request.method == "GET":
            return render(request, "rbac/delete.html", {"cancel_url": url})
        models.Permission.objects.filter(id=pk).delete()
        return redirect(url)

    rbac/forms/menu.py

    from django import forms
    from rbac import models
    from django.utils.safestring import mark_safe
    from rbac.forms.base import BootStrapModelForm
    
    
    class PermissionModelForm(BootStrapModelForm):
        class Meta:
            model = models.Permission
            fields = ["title", "name", "url"]

    rbac/templates/rbac/menu_list.html

    {% extends 'layout.html' %}
    
    {% load rbac %}
    
    {% block css %}
        <style>
            {# 选中样式css #}
            tr.active {
                border-left: 3px solid #fdc00f;
            }
        </style>
    {% endblock %}
    
    {% 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>
                        一级菜单
                        <a href="{% memory_url request 'rbac:menu_add' %}" class="right btn btn-success btn-xs"
                           style="padding: 2px 8px; margin: -3px;">
                            <i class="fa fa-plus-circle" aria-hidden="true"></i>
                            新建
                        </a>
                    </div>
    
                    <!-- Table -->
                    <table class="table">
                        <thead>
                        <tr>
                            <th>名称</th>
                            <th>图标</th>
                            <th>选项</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for menu in menus %}
                            {# safe也可以转换类型,将数值类型转为了字符串类型 #}
                            <tr class="{% if menu.id|safe == mid %}active{% endif %}">
                                <td>
                                    <a href="?mid={{ menu.id }}">{{ menu.title }}</a>
                                </td>
                                <td>
                                    <i class="fa {{ menu.icon }}" aria-hidden="true"></i>
                                </td>
                                <td>
                                    <a style="color: #333333;" href="{% memory_url request 'rbac:menu_edit' pk=menu.id %}">
                                        <i class="fa fa-edit" aria-hidden="true"></i></a>
                                    <a style="color: #d9534f;" href="{% memory_url request 'rbac:menu_del' pk=menu.id %}"><i
                                            class="fa fa-trash-o"></i></a>
                                </td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
            {# 二级菜单 #}
            <div class="col-md-4">
                <div class="panel panel-default">
                    <!-- Default panel contents -->
                    <div class="panel-heading">
                        <i class="fa fa-cog" aria-hidden="true"></i>
                        二级菜单
                        {# 如果选中了一级菜单,那么就显示新建按钮 #}
                        {% if mid %}
                            <a href="{% memory_url request 'rbac:second_menu_add' menu_id=mid %}" class="right btn btn-success btn-xs"
                               style="padding: 2px 8px; margin: -3px;">
                                <i class="fa fa-plus-circle" aria-hidden="true"></i>
                                新建
                            </a>
                        {% endif %}
                    </div>
    
                    <!-- Table -->
                    <table class="table">
                        <thead>
                        <tr>
                            <th>名称</th>
                            {# 让code和url两个信息显示在同一列,这样就不会因为信息过长而影响整个页面展示 #}
                            <th>CODE&URL</th>
                            <th>选项</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for menu in second_menus %}
                            {# 如果选中,那么加active让其显示默认选中效果 #}
                            <tr class="{% if menu.id|safe == sid %}active{% endif %}">
                                {# 合并两列单元格 #}
                                <td rowspan="2">
                                    {# sid代表二级菜单的id,url如此设计能让后端获取到二级菜单id然后传给模板,模板根据判断进行默认选中效果的展示 #}
                                    <a href="?mid={{ mid }}&sid={{ menu.id }}">{{ menu.title }}</a>
                                </td>
                                <td>{{ menu.name }}</td>
                                <td>
                                    <a style="color: #333333;" href="{% memory_url request 'rbac:second_menu_edit' pk=menu.id %}">
                                        <i class="fa fa-edit" aria-hidden="true"></i></a>
                                    <a style="color: #d9534f;" href="{% memory_url request 'rbac:second_menu_del' pk=menu.id %}"><i
                                            class="fa fa-trash-o"></i></a>
                                </td>
                            </tr>
                            {# 因为是两行,所以这里也需要加一个active #}
                            <tr class="{% if menu.id|safe == sid %}active{% endif %}">
                                {# 合并两行单元格,并将上边距设置为0,这样就不会有一条横线了 #}
                                <td colspan="2" style="border-top: 0;">{{ menu.url }}</td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
            {# 权限展示 #}
            <div class="col-md-4">
                <div class="panel panel-default">
                    <!-- Default panel contents -->
                    <div class="panel-heading">
                        <i class="fa fa-cogs" aria-hidden="true"></i>
                        权限
                        {# 如果选中了二级菜单,那么就显示新建按钮 #}
                        {% if sid %}
                            <a href="{% memory_url request 'rbac:permission_add' second_menu_id=sid %}" class="right btn btn-success btn-xs"
                               style="padding: 2px 8px; margin: -3px;">
                                <i class="fa fa-plus-circle" aria-hidden="true"></i>
                                新建
                            </a>
                        {% endif %}
                    </div>
    
                    <!-- Table -->
                    <table class="table">
                        <thead>
                        <tr>
                            <th>名称</th>
                            {# 让code和url两个信息显示在同一列,这样就不会因为信息过长而影响整个页面展示 #}
                            <th>CODE&URL</th>
                            <th>选项</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for menu in permissions %}
                            <tr>
                                {# 合并两列单元格 #}
                                <td rowspan="2">
                                    {{ menu.title }}
                                </td>
                                <td>{{ menu.name }}</td>
                                <td>
                                    <a style="color: #333333;" href="{% memory_url request 'rbac:permission_edit' pk=menu.id %}">
                                        <i class="fa fa-edit" aria-hidden="true"></i></a>
                                    <a style="color: #d9534f;" href="{% memory_url request 'rbac:permission_del' pk=menu.id %}"><i
                                            class="fa fa-trash-o"></i></a>
                                </td>
                            </tr><tr>
                                {# 合并两行单元格,并将上边距设置为0,这样就不会有一条横线了 #}
                                <td colspan="2" style="border-top: 0;">{{ menu.url }}</td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    {% endblock %}
  • 相关阅读:
    SharePoint 创建 Lookup 类型的Site Column解决跨站问题
    Thinking In Design Pattern——MVP模式演绎
    SharePoint自动化部署,利用SPSD工具包
    SharePoint自动化部署,利用PowerShell 导出/导入AD中的用户
    64位内核第十四讲,获取系统滴答数与日期时间
    内核中通过进程PID获取进程的全部路径
    内核中根据进程Pid获取卷的全目录
    内核中PID_HANDLE_OBJECT等互相转换
    获取指定句柄的类型号.
    获取句柄的类型以及对应的ID序号
  • 原文地址:https://www.cnblogs.com/xuewei95/p/15875659.html
Copyright © 2020-2023  润新知