效果图:
为了方便开发,先把中间件注释掉,要不还要在角色-权限表中添加对应关系。又因为二级菜单和面包屑导航需要中间件的变量,所以要在layout.html里面把这两个也注释掉。
setting.py
# 'rbac.middlewares.rbac.RbacMiddleware'
layout.html
{# {% multi_menu request %} #} {# {% breadcrumb request %} #}
一、路由分发
在主目录的urls.py下给rbac做分发
from django.urls import path, re_path, include urlpatterns = [ # rbac re_path(r'^rbac/', include(('rbac.urls', 'rbac'))) ]
给rbac下的urls.py里配置路由
from django.urls import re_path from rbac.views import role 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'), ]
二、增加form表单验证
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/role.py
from django import forms from rbac import models from rbac.forms.base import BaseBootStrapForm class RoleModelForm(BaseBootStrapForm): class Meta: model = models.Role fields = ['title', ]
三、在视图函数写增删改查的功能
rbac/views/role.py
""" 角色管理 """ from django.shortcuts import render, redirect from django.urls import reverse from rbac import models from rbac.forms.roles import RoleModelForm def role_list(request): """ 角色列表 :param request: :return: """ role_queryset = models.Role.objects.all() return render(request, 'rbac/role_list.html', {'role_list': role_queryset}) def role_add(request): """ 添加角色 :param request: :return: """ if request.method == 'GET': forms = RoleModelForm() return render(request, 'rbac/change.html', {'forms': forms}) forms = RoleModelForm(data=request.POST) if forms.is_valid(): forms.save() return redirect(reverse('rbac:role_list')) return render(request, 'rbac/change.html', {'forms': forms}) def role_edit(request, pk): """ 编辑角色 :param request: :param pk: 要修改的角色id :return: """ role_obj = models.Role.objects.filter(id=pk).first() if request.method == 'GET': forms = RoleModelForm(instance=role_obj) return render(request, 'rbac/change.html', {'forms': forms}) forms = RoleModelForm(data=request.POST, instance=role_obj) if forms.is_valid(): forms.save() return redirect(reverse('rbac:role_list')) return render(request, 'rbac/change.html', {'forms': forms}) def role_del(request, pk): """ 删除角色 :param request: :param pk: :return: """ role_list_url = reverse('rbac:role_list') if request.method == 'GET': return render(request, 'rbac/delete.html', {'cancel': role_list_url}) models.Role.objects.filter(id=pk).delete() return redirect(role_list_url)
增加和编辑可以用一个页面。删除页面给其他表做增删改查的时候也可以用,所以这里要给页面传一个固定参数cancel,以后其他表也要传这个参数。
四、渲染到模板
rbac/templates/role_list.html
{% extends 'layout.html' %} {% block content %} <h1>角色列表</h1> <div class="luffy-container"> <div class="btn-group" style="margin:5px 0"> <a class="btn btn-default" href="{% url 'rbac:role_add' %}"> <i class="fa fa-plus-square" aria-hidden="true"></i>添加角色 </a> </div> <table class="table table-hover table-striped"> <thead> <tr> <th>id</th> <th>名称</th> <th>选项</th> </tr> </thead> <tbody> {% for role in role_list %} <tr> <td>{{ role.id }}</td> <td>{{ role.title }}</td> <td> <a style="color: #333333; font-size:18px" href="{% url 'rbac:role_edit' pk=role.id %}"> <i class="fa fa-edit" aria-hidden="true"></i> </a> <a style="color: red; font-size:18px" href="{% url 'rbac:role_del' pk=role.id %}"> <i class="fa fa-trash-o" aria-hidden="true"></i> </a> </td> </tr> {% endfor %} </tbody> </table> </div> {% endblock content %}
rbac/templates/change.html
{% extends 'layout.html' %} {% block content %} <div class="luffy-container"> <form action="" method="post" novalidate> {% csrf_token %} {% for field in forms %} <div class="form-group"> <label for="{{ field.auto_id }}">{{ field.label }}</label> {{ field }} <span style="color:red;">{{ field.errors.0 }}</span> </div> {% endfor %} <input type="submit" value="提交" class="btn btn-primary"> </form> </div> {% endblock content %}
rbac/templates/delete.html
{% extends 'layout.html' %} {% block content %} <div class="luffy-container"> <div class="alert alert-danger" role="alert"> <form action="" method="post" novalidate> {% csrf_token %} <p style="font-size: 13px;"><i class="fa fa-warning" aria-hidden="true"></i>删除后将不可恢复,请确认是否删除</p> <div style="margin-top: 20px"> <a href="{{ cancel }}" class="btn btn-default btn-sm">取消</a> <input type="submit" value="确认" class="btn btn-danger btn-sm"/> </div> </form> </div> </div> {% endblock content %}