先来看一看我的,数据库的表:
权限表: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})
删除

 

posted on 2019-04-15 18:11  rookiehbboy  阅读(1017)  评论(0编辑  收藏  举报