models.py
from django.db import models
class User(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) roles=models.ManyToManyField(to="Role")
def __str__(self): return self.name class Role(models.Model): title=models.CharField(max_length=32) permissions=models.ManyToManyField(to="Permission") def __str__(self): return self.title class Permission(models.Model): title=models.CharField(max_length=32) url=models.CharField(max_length=32) action=models.CharField(max_length=32,default="") group=models.ForeignKey("PermissionGroup",default=1) def __str__(self):return self.title class PermissionGroup(models.Model): title = models.CharField(max_length=32) def __str__(self): return self.title
admin.py
from django.contrib import admin # Register your models here. from .models import * class PerConfig(admin.ModelAdmin): list_display = ["title","url","group","action"] admin.site.register(User) admin.site.register(Role) admin.site.register(Permission,PerConfig) admin.site.register(PermissionGroup)
templatetags-->my_tags.py
from django import template
from rbac.service.rbac import reg
register=template.Library()
@register.inclusion_tag("rbac/menu.html")
def get_menu(request,):
# 获取当前用户可以放到菜单栏中的权限
menu_permission_list = request.session["menu_permission_list"]
return {"menu_permission_list":menu_permission_list}
@register.simple_tag
def valid(link,request):
from bs4 import BeautifulSoup
soup=BeautifulSoup(link,"html.parser")
print(soup.a.get('href'))
path=soup.a.get('href')
flag=reg(request,path)
if flag:
return link
else:return ""
service-->perssions.py
def initial_session(user, request):
# 方案1
# [{},{},{}]
# permissions = user.roles.all().values("permissions__url").distinct() #distinct去重
#
# permission_list = []
#
# #循环字典拿到每个字典对应的字段,只放url
# for item in permissions:
# permission_list.append(item["permissions__url"])
# print(permission_list)
#
# request.session["permission_list"] = permission_list
# 方案2
permissions = user.roles.all().values("permissions__url", "permissions__group_id", "permissions__action").distinct()
print("permissions", permissions)
permission_dict = {}
for item in permissions:
gid = item.get('permissions__group_id')
if not gid in permission_dict:
permission_dict[gid] = {
"urls": [item["permissions__url"], ],
"actions": [item["permissions__action"], ]
}
else:
permission_dict[gid]["urls"].append(item["permissions__url"])
permission_dict[gid]["actions"].append(item["permissions__action"])
# print(permission_dict)
request.session['permission_dict'] = permission_dict
# 注册菜单权限
permissions = user.roles.all().values("permissions__url", "permissions__action","permissions__group__title").distinct()
# print("permissions", permissions)
menu_permission_list = []
for item in permissions:
if item["permissions__action"] == "list":
menu_permission_list.append((item["permissions__url"], item["permissions__group__title"]))
# print(menu_permission_list)
request.session["menu_permission_list"] = menu_permission_list
service-->rbac.py
import re from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse,redirect def reg(request,current_path): # 校验权限1(permission_list) permission_list = request.session.get("permission_list", []) flag = False for permission in permission_list: permission = "^%s$" % permission ret = re.match(permission, current_path) if ret: flag = True break return flag class ValidPermission(MiddlewareMixin): def process_request(self,request): # 当前访问路径 current_path = request.path_info # 检查是否属于白名单 valid_url_list=["/login/","/reg/","/admin/.*"] for valid_url in valid_url_list: ret=re.match(valid_url,current_path) if ret: return None # 校验是否登录 user_id=request.session.get("user_id") if not user_id: return redirect("/login/") # 校验权限 (permission_list) # permission_list = request.session.get("permission_list",[]) # ['/users/', '/users/add', '/users/delete/(\\d+)', 'users/edit/(\\d+)'] # # flag = False # for permission in permission_list: # # permission = "^%s$" % permission # # ret = re.match(permission, current_path) # if ret: # flag = True # break # if not flag: # return HttpResponse("没有访问权限!") # # return None # 校验权限2 permission_dict=request.session.get("permission_dict") for item in permission_dict.values(): urls=item['urls'] for reg in urls: reg="^%s$"%reg ret=re.match(reg,current_path) if ret: print("actions",item['actions']) request.actions=item['actions'] return None return HttpResponse("没有访问权限!")
urls.py
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^users/$', views.users), url(r'^users/add', views.add_user), url(r'^users/delete/(\d+)', views.del_user), url(r'^roles/', views.roles), url(r'^login/', views.login), ]
app01--views.py
from django.shortcuts import render,HttpResponse # Create your views here. from rbac.models import * class Per(object): def __init__(self,actions): self.actions=actions def add(self): return "add" in self.actions def delete(self): return "delete" in self.actions def edit(self): return "edit" in self.actions def list(self): return "list" in self.actions def users(request): user_list=User.objects.all() # 查询当前登录人得名字 id = request.session.get("user_id") user = User.objects.filter(id=id).first() per=Per(request.actions) return render(request, "users.html", locals()) import re def add_user(request): return HttpResponse("add user.....") def del_user(request,id): return HttpResponse("del"+id) def roles(request): role_list=Role.objects.all() return render(request,"roles.html",locals()) from rbac.service.perssions import * def login(request): if request.method=="POST": user=request.POST.get("user") pwd=request.POST.get("pwd") user=User.objects.filter(name=user,pwd=pwd).first() if user: ############################### 在session中注册用户ID###################### request.session["user_id"]=user.pk ###############################在session注册权限列表############################## # 查询当前登录用户的所有角色 # ret=user.roles.all() # print(ret)# <QuerySet [<Role: 保洁>, <Role: 销售>]> # 查询当前登录用户的所有权限 initial_session(user,request) return HttpResponse("登录成功!") return render(request,"login.html")
rbac---> template--->rbac---> users.html
{% extends 'base.html'%}
{% block con %}
{% valid '<a href="/users/add/" class="btn btn-primary">添加用户</a>' request %} <h4>用户列表</h4> {% if per.add %} <a href="users/add/" class="btn btn-primary">添加用户</a> {% endif %} <table class="table table-bordered table-striped"> <thead> <tr> <th>序号</th> <th>姓名</th> <th>角色</th> <th>操作</th> </tr> </thead> <tbody> {% for user in user_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ user.name }}</td> <td> {% for role in user.roles.all %} {{ role.title }} {% endfor %} </td> <td> {% if per.delete %} <a href="/users/delete/{{ user.pk }}" class="btn btn-danger">删除</a> {% endif %} {% if per.edit %} <a href="" class="btn btn-warning">编辑</a> {% endif %} </td> </tr> {% endfor %} </tbody> </table>
{% endblock %}
rbac---> template--->rbac---> roles.html
{% extends 'rbac/base.html' %} {% block con %} <h4>角色列表</h4> {% if per.add %} <a href="" class="btn btn-primary">添加角色</a> {% endif %} <table class="table table-bordered table-striped"> <tbody> {% for role in role_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ role.title }}</td> <td> {% if per.delete %} <a href="/roles/delete/{{ user.pk }}" class="btn btn-danger">删除</a> {% endif %} {% if per.edit %} <a href="/roles/edit/{{ user.pk }}" class="btn btn-warning">编辑</a> {% endif %} </td> </tr> {% endfor %} </tbody> </table> {% endblock %}
rbac---> template--->rbac---> menu.html
<div> {% for item in menu_permission_list %} <p class="menu_btn"><a href="{{ item.0 }}">{{ item.1 }}</a></p> {% endfor %} </div>
rbac---> template--->rbac---> base.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <style> *{ margin: 0; padding: 0; } .header{ width: 100%; height: 60px; background-color: #336699; } .menu{ background-color: bisque; position: fixed; top: 60px; bottom: 0px; left: 0px; width: 200px; } .content{ position: fixed; top: 60px; bottom: 0; right: 0; left: 200px; overflow: auto; padding: 30px; } .menu_btn{ font-size: 15px; text-align: center; padding: 30px 0; } .header .title{ color: white; font-size: 18px; margin-right: 20px; font-weight: 100; } </style> </head> <body> <div class="header"> <p class="title pull-right">{{ user.name }}</p> </div> <div class="contain"> {% load my_tags %} <div class="menu"> {% get_menu request %} </div> <div class="content"> {% block con %} {% endblock %} </div> </div> </body> </html>