• 权限组件(10):三级菜单的展示和增删改查


    效果图:

    三级菜单的实现和一级、二级菜单差不多。需要注意的是增加三级菜单时,三级菜单是用户提交后在后台通过二级菜单的id添加的。 

    一、路由分发

    rbac/urls.py

    ...
    from django.urls import re_path
    
    from rbac.views import menu
    ...
    
    urlpatterns = [
        ...
        # 三级菜单
        re_path(r'^permission/add/(?P<second_menu_id>d+)/$', menu.permission_add, name='permission_add'),
        re_path(r'^permission/edit/(?P<pk>d+)/$', menu.permission_edit, name='permission_edit'),
        re_path(r'^permission/del/(?P<pk>d+)/$', menu.permission_del, name='permission_del'),
        ...
    ]

    二、forms表单验证

    rbac/forms/base.py

    from django import forms
    
    
    class BaseBootStrapForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            for name, field in self.fields.items():
                field.widget.attrs['class'] = 'form-control'
    
    

    rbac/forms/menus.py

    ...
    from rbac import models
    from rbac.forms.base import BaseBootStrapForm
    ...
    
    ...
    class PermissionModelForm(BaseBootStrapForm):
        class Meta:
            model = models.Permission
            fields = ['title', 'name', 'url']
    ...

    三、视图函数

    rbac/views/menu.py 

    from django.shortcuts import HttpResponse, render, redirect, reverse
    
    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:
        """
        menu_queryset = models.Menu.objects.all()
    
        menu_id = request.GET.get('mid')  # 用户选择的一级菜单
    
        menus_exists = models.Menu.objects.filter(id=menu_id).exists()
    
        if not menus_exists:
            menu_id = None
    
        if menu_id:
            second_menus = models.Permission.objects.filter(menu_id=menu_id)
        else:
            second_menus = []
    
        second_menu_id = request.GET.get('sid')  # 用户选择的二级菜单  #  +
    
        second_menus_exists = models.Permission.objects.filter(id=second_menu_id).exists()  #  +
    
        if not second_menus_exists:  #  +
            second_menu_id = None  #  +
    
        if second_menu_id:  #  +
            permissions = models.Permission.objects.filter(pid__id=second_menu_id)  #  +
        else:  #  +
            permissions = []  #  +
    
        context = {
            'menu_list': menu_queryset,
            'menu_id': menu_id,
            'second_menus': second_menus,
            'second_menu_id': second_menu_id,
            'permissions': permissions  #  +
        }
    
        return render(request, 'rbac/menu_list.html', context)
    
    ...
    
    # 权限的增删改
    
    def permission_add(request, second_menu_id):
        """
        添加权限
        :param request:
        :param pk:
        :return:
        """
    
        if request.method == 'GET':
            forms = PermissionModelForm()
            return render(request, 'rbac/change.html', {'forms': forms})
    
        forms = PermissionModelForm(data=request.POST)
        if forms.is_valid():
            second_menu_obj = models.Permission.objects.filter(id=second_menu_id).first()
            if not second_menu_obj:
                return HttpResponse('二级菜单不存在,请重新选择')
            forms.instance.pid = second_menu_obj  # form.instance中包含用户提交的所有值
            forms.save()
            url = memory_reverse(request, 'rbac:menu_list')
            return redirect(url)
        return render(request, 'rbac/change.html', {'forms': forms})
    
    
    def permission_edit(request, pk):
        """
        权限编辑
        :param request:
        :param pk: 要编辑的权限id
        :return:
        """
        permission_obj = models.Permission.objects.filter(id=pk).first()
    
        if request.method == 'GET':
            forms = PermissionModelForm(instance=permission_obj)
            return render(request, 'rbac/change.html', {'forms': forms})
    
        forms = PermissionModelForm(data=request.POST, instance=permission_obj)
        if forms.is_valid():
            forms.save()
            url = memory_reverse(request, 'rbac:menu_list')
            return redirect(url)
        return render(request, 'rbac/change.html', {'forms': forms})
    
    
    def permission_del(request, pk):
        """
        权限删除
        :param request:
        :param pk:
        :return:
        """
        menu_list_url = memory_reverse(request, 'rbac:menu_list')
    
        if request.method == 'GET':
            return render(request, 'rbac/delete.html', {'cancel': menu_list_url})
    
        models.Permission.objects.filter(id=pk).delete()
    
        return redirect(menu_list_url)

    四、模板渲染

    rbac/templates/menu_list.html

    {% extends 'layout.html' %}
    {% load rbac %}
    
    <style>
        tr.active {
            border-left: 3px solid #fdc00f;
        }
    </style>
    
    {% 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 menu_list %}
                            <!-- 管道符可以将后端传来的整型,转换成字符串 -->
                            <tr class="{% if menu.id|safe == menu_id %}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; font-size:18px"
                                       href="{% memory_url request 'rbac:menu_edit' pk=menu.id %}">
                                        <i class="fa fa-edit" aria-hidden="true"></i>
                                    </a>
    
                                    <a style="color: red; font-size:18px"
                                       href="{% memory_url request 'rbac:menu_del' pk=menu.id %}">
                                        <i class="fa fa-trash-o" aria-hidden="true"></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-flag" aria-hidden="true">二级菜单</i>
                        {% if menu_id %}
                            <a href="{% memory_url request 'rbac:second_menu_add' menu_id=menu_id %}"
                               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>
                            <td>名称</td>
                            <td>CODE&URL</td>
                            <td>选项</td>
                        </tr>
                        </thead>
    
                        <tbody>
                        {% for second_menu in second_menus %}
                            <!-- 管道符可以将后端传来的整型,转换成字符串 -->
                            <tr class="{% if second_menu.id|safe == second_menu_id %}active{% endif %}">
                                <td rowspan="2">
                                    <a href="?mid={{ menu_id }}&sid={{ second_menu.id }}">{{ second_menu.title }}</a>
                                </td>
                                <td>{{ second_menu.name }}</td>
    
                                <td>
                                    <a href="{% memory_url request 'rbac:second_menu_edit' pk=second_menu.id %}"
                                       style="color:#333333;font-size:18px;">
                                        <i class="fa fa-edit" aria-hidden="true"></i>
                                    </a>
    
                                    <a href="{% memory_url request 'rbac:second_menu_del' pk=second_menu.id %}"
                                       style="color:red;font-size:18px;">
                                        <i class="fa fa-trash-o" aria-hidden="true"></i>
                                    </a>
                                </td>
                            </tr>
    
    
                            <tr class="{% if second_menu.id|safe == second_menu_id %}active{% endif %}">
                                <td colspan="2" style="border-top:0;">{{ second_menu.url }}</td>
                            </tr>
    
                        {% endfor %}
    
                        </tbody>
                    </table>
                </div>
            </div>
    
            <!-- 权限表 -->
            <div class="col-md-5">
                <div class="panel panel-default">
                    <!-- Default panel contents -->
                    <div class="panel-heading">
                        <i class="fa fa-bookmark" aria-hidden="true">三级菜单</i>
                        {% if menu_id %}
                            {% if second_menu_id %}
                                <a href="{% memory_url request 'rbac:permission_add' second_menu_id=second_menu_id %}"
                                   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 %}
                        {% endif %}
                    </div>
    
                    <!-- Table -->
                    <table class="table">
                        <thead>
                        <tr>
                            <td>名称</td>
                            <td>CODE&URL</td>
                            <td>选项</td>
                        </tr>
                        </thead>
    
                        <tbody>
                        {% for permission in permissions %}
                            <tr>
                                <td rowspan="2">{{ permission.title }}</td>
                                <td>{{ permission.name }}</td>
    
                                <td>
                                    <a href="{% memory_url request 'rbac:permission_edit' pk=permission.id %}"
                                       style="color:#333333;font-size:18px;">
                                        <i class="fa fa-edit" aria-hidden="true"></i>
                                    </a>
    
                                    <a href="{% memory_url request 'rbac:permission_del' pk=permission.id %}"
                                       style="color:red;font-size:18px;">
                                        <i class="fa fa-trash-o" aria-hidden="true"></i>
                                    </a>
                                </td>
                            </tr>
    
                            <tr>
                                <td colspan="2" style="border-top:0;">{{ permission.url }}</td>
                            </tr>
    
                        {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    
    
    {% endblock content %}

    需要注意的是选择了一级和二级菜单后才会显示三级菜单的相关信息。增删改页面无需变动。

  • 相关阅读:
    HUD --- 3635
    leetcode380- Insert Delete GetRandom O(1)- medium
    leetcode68- Text Justification- hard
    leetcode698- Partition to K Equal Sum Subsets- medium
    leetcode671- Second Minimum Node In a Binary Tree- easy
    leetcode647- Palindromic Substrings- medium
    leetcode633- Sum of Square Numbers- easy
    leetcode605- Can Place Flowers- easy
    leetcode515- Find Largest Value in Each Tree Row- medium
    leetcode464- Can I Win- medium
  • 原文地址:https://www.cnblogs.com/lshedward/p/10509290.html
Copyright © 2020-2023  润新知