zoukankan      html  css  js  c++  java
  • 权限分配之二级菜单增删改查

    先来看一看我的,数据库的表:
    权限表:Permission

    一级菜单表: Menu

    再看看,二级菜单的, 页面效果图:

    分析一波:
      1. 二级菜单是建立在一级菜单的基础上,进行展示。  这就又使用到,如何保留原搜索信息的方法,  关于携带参数的问题?
      2. 然后 二级菜单不需要单独的, 展示页面, 与 一级菜单使用同一个就可以。
      3. 新建时二级菜单时,需要明确的知道,我这个二级菜单 是 属于哪一个 一级菜单。 所以在进入 二级菜单添加页面时, 需要的参数又有一个 Menu_id 一级菜单的id

    OK  话不多说:上代码:
    先看一看url 路由的设置:

        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"),
    

     因为展示页面的 url 使用的还是, 一级菜单的路由。所以来看一看对, 一级菜单路由的  一点改动:

    def menu_list(request):
        '''
        菜单和权限列表
        :param request:
        :return:
        '''
        # menu_id = int(request.GET.get("mid"))  # 前端判断时,需要一个int类型,而不是str类型。
        menu_id = request.GET.get("mid")  # 或者在前端进行转换,将数字转换成,字符串
        second_menu_id = request.GET.get("sid")
        menu_list = models.Menu.objects.all()
        if menu_id:
            second_menus = models.Permission.objects.filter(menu_id=menu_id)
        else:
            second_menus = []
        return render(request, "rbac/menu_list.html", locals())
    

     二级菜单,多了一个需要传递的参数 sid。并且需要在Permission表中找到,属于当前点击的 一级菜单的 二级菜单(也就是 权限表中, menu_id有值的字段)
    如果一级菜单也就是 GET 请求有把一级菜单的 id 发送过来, 那么就是用户在访问二级菜单,需要查找出来。
    如果没有这个值, 那么用户就只是在访问,一级菜单。 二级菜单列表, 就应该为空。

    看看 页面模板的设计: 这里才是改动较大的地方:

    <div class="col-md-4">
                <div class="panel panel-default">
                    <!-- Default panel contents -->
                    <div class="panel-heading"><i class="fa fa-binoculars" aria-hidden="true"></i> 二级菜单
                        {% if second_menus %}
                            <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>
                            <th>名称</th>
                            <th>URL & CODE</th>
                            <th>选项</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for menu in second_menus %}
                            <tr class="{% if second_menu_id == menu.pk|safe %}active{% endif %}">
                                <th rowspan="2"><a href="?mid={{ menu_id }}&sid={{ menu.pk }}">{{ menu.title }}</a></th>
                                <td>{{ menu.name }}</td>
                                <td>
                                    <a style="color: #333333;" href="{% memory_url request 'rbac:second_menu_edit' pk=menu.pk %}">
                                        <i class="fa fa-edit" aria-hidden="true"></i></a>
                                    <a style="color: #d9534f;" href="{% memory_url request 'rbac:second_menu_del' pk=menu.pk %}"><i
                                            class="fa fa-trash-o"></i></a>
                                </td>
                            </tr>
                            <tr class="{% if second_menu_id == menu.pk|safe %}active{% endif %}">
                                <td colspan="2" style=" border-top: 0">{{ menu.url }}</td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
    二级菜单  同属菜单展示页面。  只展示二级菜单的东西。

    和一级菜单,不同的地方:
      1. 二级菜单添加按钮  的路由。因为需要的不仅仅是自身的地址  还需要加上,当天我要往 那个一级菜单添加的。这个一级菜单的id
      href="{% memory_url request 'rbac:second_menu_add' menu_id=menu_id %}"

    二级菜单,添加的 视图函数:

    def second_menu_add(request, menu_id):
        '''
        二级菜单添加视图
        :param request:
        :param menu_id:  已经选中的一级菜单的id(用于设置默认值)
        :return:
        '''
        menu_obj = models.Menu.objects.filter(pk=menu_id).first()
        if request.method == "POST":
            forms = SecondMenuForm(request.POST)
            if forms.is_valid():
                forms.save()
                return redirect(memory_reverse(request, "rbac:menu_list"))
            else:
                return render(request, "rbac/change.html", {"forms": forms})
        forms = SecondMenuForm(initial={"menu": menu_obj})
        # 为一级菜单menu字段, 添加默认值。
        return render(request, "rbac/change.html", {"forms": forms}er 
    二级菜单 视图函数:

    因为添加的是二级 菜单。所以依然是 使用的form组件来完成这件事。

    class SecondMenuForm(BootstrapModelForm):
        '''菜单form'''
    
        class Meta:
            model = models.Permission
            exclude = ["pid"]
    
        def __init__(self, *args, **kwargs):
            super(SecondMenuForm, self).__init__(*args, **kwargs)
            for name, field in self.fields.items():
                field.widget.attrs["class"] = "form-control"
    Permission 表中有5个字段, 分别是: title、 url、 name、 menu、 pid 。

    title 是标题,是需要进行展示的。 url 是路由。 name 是别名, menu是属于哪一个一级菜单。 pid 是此条url 属于那一条url 的子菜单(或着子权限)。比如: 添加客户权限属于客户列表权限的子权限。  他不能属于, 账户列表。
    so  明白了,我们需要添加时,需要添加4个字段。  pid 是不需要的。  所以使用exclude = ["pid"]  剔除掉这个字段。

    并且,有一点。 menu这个字段,展示的时候是一个select, 需要有一个默认选择的选项。 也就是我是点击哪一个一级菜单进来的。 这样就可以修改属于哪一个一级菜单:
    视图函数代码:

    def second_menu_add(request, menu_id):
        '''
        二级菜单添加视图
        :param request:
        :param menu_id:  已经选中的一级菜单的id(用于设置默认值)
        :return:
        '''
        menu_obj = models.Menu.objects.filter(pk=menu_id).first()
        if request.method == "POST":
            forms = SecondMenuForm(request.POST)
            if forms.is_valid():
                forms.save()
                return redirect(memory_reverse(request, "rbac:menu_list"))
            else:
                return render(request, "rbac/change.html", {"forms": forms})
        forms = SecondMenuForm(initial={"menu": menu_obj})
        # 为一级菜单menu字段, 添加默认值。
        return render(request, "rbac/change.html", {"forms": forms})
    

     这里上文,提到的一级菜单menu_id 就使用到了。
    最初展示的时候, 使用forms = SecondMenuForm(initial={"menu": menu_obj})  initial参数, 为指定的menu字段添加上,需要默认展示的字段。
    也就是 从数据库中,取出  pk=menu_id 的 model对象。

    剩下的, 编辑和删除:也就是 一样的代码:
    唯一需要知道的就是, 编辑和删除, 就不需要menu_id 这个参数, 来进行默认的展示。
    因为所有的数据,已经存入的数据库里。 直接从数据库中,取出来在进行渲染就好。

    def second_menu_edit(request, pk):
        '''
    
        :param request:
        :param pk: 当前要编辑的二级菜单, 为什么这了不需要menu_id 了呢? 因为数据库已经做好了关联,所有不需要了
        :return:
        '''
        permission_obj = models.Permission.objects.filter(pk=pk).first()
        if not permission_obj:
            return HttpResponse("菜单不存在")
    
        if request.method == "POST":
            forms = SecondMenuForm(instance=permission_obj, data=request.POST)
            if forms.is_valid():
                forms.save()
                return redirect(memory_reverse(request, "rbac:menu_list"))
            else:
                return render(request, "rbac/change.html", {"forms": forms})
        forms = SecondMenuForm(instance=permission_obj)  # 将查询出来的对象交给form组件, 进行渲染。
        # instance 就是接收一个 从数据库中,取出的模型表的这样一个数据。
    
        # 这里为什么返回的是,添加的页面? 因为添加个编辑一模一样, 只是input框中有数据而已。 而我现在的forms中已经有了数据
        return render(request, "rbac/change.html", {"forms": forms})
    编辑
    def second_menu_del(request, pk):
        '''
        删除操作, 需要给与用户提示。
        :param reuqest:
        :param pk:  要删除的权限id
        :return:
        '''
        origin_url = memory_reverse(request, "rbac:menu_list")
        permission_queryset = models.Permission.objects.filter(pk=pk)
        if not permission_queryset:
            return HttpResponse("菜单不存在")
        if request.method == "POST":
            permission_queryset.delete()
            return redirect(origin_url)
        return render(request, "rbac/delete.html", {"cancel": origin_url})
    删除
  • 相关阅读:
    宝宝打疫苗
    【小工具】2. 需要对测试用的数据进行MD5加密
    【小工具】1.需要对txt存放的测试数据做去重处理
    【Jenkins】定时构建语法
    【bug】记一个有趣的“bug”
    1.由于测试某个功能,需要生成500W条数据的txt,python代码如下
    开发基于vue前端框架下的系统的UI自动化,记录总结踩的坑
    使用Chrome-headless模式下,截屏不全屏的问题
    Chrome-headless 模式,没有UI界面的自动化UI测试
    【selenium】Webdriver的原理以及工作流程
  • 原文地址:https://www.cnblogs.com/chengege/p/10712121.html
Copyright © 2011-2022 走看看