权限管理——版本3
權限管理——版本3
1.目標
-解決版本的BUG,即,當我們點擊添加/刪除/編輯時,菜單的首頁都會縮小,按理說:不應該縮小。
-看看最終的實現:
點擊添加之后,注意看左邊的菜單管理,按理是不應該縮小的,但是之前的版本2是會縮小的,所以需要解決這個問題。
解決方案思路:
解決:1.找到當前點擊進入的url,找到這個url的組,讓這個組默認選中菜單就可以。- 請求url:request.path_info- 所有的url; ..... -以上兩個一一匹配,成功之后,找到組id,通過組id找到當前組里的"is_menu"=True的這條記錄,在它后面加個active = True為默認被選中。然后需要再一次循環,把is_menu為True取出來,讓這兩生成菜單就可以了。前提:一組一個菜單2.修改數據庫的記錄。1.方法1:在權限表加一個組內菜單的字段,自關聯。null 就為菜單/userinfo/ list null 組1/userinfo/add add 1 組1/userinfo/edit edit 1 組1/userinfo/del del 1 組1/order/ list null 組2/order/add add 5 組2/order/edit edit 5 組2/order/del del 5 組22.方法2:設一個菜單字典:menu_dict = {1:{'id':1,'title':'用戶列表','url':'/userinfo/','menu_gp_id':None,'menu_id':1,'menu_title':'菜單管理',active=True}5:{'id':5,'title':'訂單列表','url':'/order/','menu_gp_id':None,'menu_id':2,'menu_title':'訂單管理'}}current_url = request.path_infofor item in menu_list:url = item['url']regex = '^{0}$'format(url)if re.match(regex,current_url):menu_gp_id = item['menu_gp_id']if not menu_gp_id:#給自己加active = True,下面兩個方式都可以用,因為用的是同一個引用。item['active'] = Truemenu_dict[item]['id']['active']=Trueelse:menu_dict[menu_gp_id]['active'] = True
?
?
2.代碼
app01/views.py:
import refrom django.shortcuts import render,redirect,HttpResponse from django.conf import settings from rbac import models from rbac.service.init_permission import init_permission def login(request):if request.method == "GET":return render(request,'login.html')else:user = request.POST.get('user')pwd = request.POST.get('pwd')user = models.User.objects.filter(username=user,password=pwd).first()print(request.POST)if not user:return render(request, 'login.html')init_permission(user,request)return redirect('/index/')def index(request):return HttpResponse('歡迎登錄')class BasePagePermission(object):def __init__(self,code_list):self.code_list = code_listdef has_add(self):if "add" in self.code_list:return Truedef has_edit(self):if 'edit' in self.code_list:return Truedef has_del(self):if 'del' in self.code_list:return Truedef userinfo(request):page_permission = BasePagePermission(request.permission_code_list)data_list = [{'id':1,'name':'xxx1'},{'id':2,'name':'xxx2'},{'id':3,'name':'xxx3'},{'id':4,'name':'xxx4'},{'id':5,'name':'xxx5'},]return render(request,'userinfo.html',{'data_list':data_list,'page_permission':page_permission})def userinfo_add(request):page_permission = BasePagePermission(request.permission_code_list)return render(request, 'userinfo_add.html', { 'page_permission': page_permission})class OrderPagePermission(BasePagePermission):def has_report(self):if 'report' in self.code_list:return Truedef order(request):order_permission = OrderPagePermission(request.permission_code_list)return render(request,'order.html')def order_add(request):return HttpResponse('添加訂單頁面') View Code?
settings.py:
?
?
urls.py:
from django.conf.urls import urlfrom django.contrib import admin
from rbac import views
from app01 import views as app01_views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/', views.test),
url(r'^login/', app01_views.login),
url(r'^index/', app01_views.index),
url(r'^userinfo/$', app01_views.userinfo),
url(r'^userinfo/add/$', app01_views.userinfo_add),
url(r'^order/$', app01_views.order),
url(r'^order/add/$', app01_views.order_add),
]
?
?rbac\middlewares\rbac.py:
import refrom django.shortcuts import redirect,HttpResponse from django.conf import settingsclass MiddlewareMixin(object):def __init__(self, get_response=None):self.get_response = get_responsesuper(MiddlewareMixin, self).__init__()def __call__(self, request):response = Noneif hasattr(self, 'process_request'):response = self.process_request(request)if not response:response = self.get_response(request)if hasattr(self, 'process_response'):response = self.process_response(request, response)return responseclass RbacMiddleware(MiddlewareMixin):def process_request(self,request):# 1. 獲取當前請求的URL# request.path_info# 2. 獲取Session中保存當前用戶的權限# request.session.get("permission_url_list')current_url = request.path_info# 當前請求不需要執行權限驗證for url in settings.VALID_URL:if re.match(url,current_url):return Nonepermission_dict = request.session.get(settings.PERMISSION_URL_DICT_KEY)if not permission_dict:return redirect('/login/')flag = Falsefor group_id,code_url in permission_dict.items():for db_url in code_url['urls']:regax = "^{0}$".format(db_url)if re.match(regax, current_url):request.permission_code_list = code_url['codes']flag = Truebreakif flag:breakif not flag:return HttpResponse('無權訪問') View Code?
rbac\service\init_permission.py
from django.conf import settingsdef init_permission(user,request):"""初始化權限信息,獲取權限信息并放置到session中。:param user::param request::return:"""permission_list = user.roles.values('permissions__id','permissions__title', # 用戶列表'permissions__url','permissions__code','permissions__menu_gp_id', # 組內菜單ID,Null表示是菜單'permissions__group_id','permissions__group__menu_id', # 菜單ID'permissions__group__menu__title',# 菜單名稱 ).distinct()# 菜單相關(以后再匹配)sub_permission_list = []for item in permission_list:tpl = {'id':item['permissions__id'],'title':item['permissions__title'],'url':item['permissions__url'],'menu_gp_id':item['permissions__menu_gp_id'],'menu_id':item['permissions__group__menu_id'],'menu_title':item['permissions__group__menu__title'],}sub_permission_list.append(tpl)request.session[settings.PERMISSION_MENU_KEY] = sub_permission_list# 權限相關result = {}for item in permission_list:group_id = item['permissions__group_id']code = item['permissions__code']url = item['permissions__url']if group_id in result:result[group_id]['codes'].append(code)result[group_id]['urls'].append(url)else:result[group_id] = {'codes':[code,],'urls':[url,]}request.session[settings.PERMISSION_URL_DICT_KEY] = result View Code?
?rbac.css
.item-permission{padding: 3px 10px; } .item-permission a{display: block; } .item-permission a.active{color: red; } .hide{display: none; }?
rbac.js
/*** Created by Administrator on 2017/11/8.*/$(function () {$('.item-title').click(function () {if($(this).next().hasClass('hide')){$(this).next().removeClass('hide')}else{$(this).next().addClass('hide')}})});?
rbac\templatetags\rbac.py
import re from django.template import Library from django.conf import settings register = Library()@register.inclusion_tag("xxxxx.html") def menu_html(request):"""去Session中獲取菜單相關信息,匹配當前URL,生成菜單:param request::return:"""menu_list = request.session[settings.PERMISSION_MENU_KEY]current_url = request.path_infomenu_dict = {}for item in menu_list:if not item['menu_gp_id']:menu_dict[item['id']] = itemfor item in menu_list:regex = "^{0}$".format(item['url'])if re.match(regex,current_url):menu_gp_id = item['menu_gp_id']if menu_gp_id:menu_dict[menu_gp_id]['active'] = Trueelse:menu_dict[item['id']]['active'] = Trueresult = {}for item in menu_dict.values():active = item.get('active')menu_id = item['menu_id']if menu_id in result:result[menu_id]['children'].append({ 'title': item['title'], 'url': item['url'],'active':active})if active:result[menu_id]['active'] = Trueelse:result[menu_id] = {'menu_id':item['menu_id'],'menu_title':item['menu_title'],'active':active,'children':[{ 'title': item['title'], 'url': item['url'],'active':active}]}return {'menu_dict':result} View Code?
rbac\models.py
from django.db import modelsclass Menu(models.Model):"""菜單組"""title = models.CharField(max_length=32)class Group(models.Model):"""權限組"""caption = models.CharField(verbose_name='組名稱',max_length=16)menu = models.ForeignKey(verbose_name='所屬菜單',to='Menu',default=1)class Permission(models.Model):"""權限表"""title = models.CharField(verbose_name='標題',max_length=32)url = models.CharField(verbose_name="含正則URL",max_length=64)menu_gp = models.ForeignKey(verbose_name='組內菜單',to='Permission',null=True,blank=True,related_name='x1')code = models.CharField(verbose_name="代碼",max_length=16)group = models.ForeignKey(verbose_name='所屬組',to="Group")class Meta:verbose_name_plural = "權限表"def __str__(self):return self.titleclass User(models.Model):"""用戶表"""username = models.CharField(verbose_name='用戶名',max_length=32)password = models.CharField(verbose_name='密碼',max_length=64)email = models.CharField(verbose_name='郵箱',max_length=32)roles = models.ManyToManyField(verbose_name='具有的所有角色',to="Role",blank=True)class Meta:verbose_name_plural = "用戶表"def __str__(self):return self.usernameclass Role(models.Model):"""角色表"""title = models.CharField(max_length=32)permissions = models.ManyToManyField(verbose_name='具有的所有權限',to='Permission',blank=True)class Meta:verbose_name_plural = "角色表"def __str__(self):return self.title View Code?
layout.html:
{% load rbac %} <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/static/rbac/rbac.css" /><title>Title</title> </head> <body><div style="float: left;width: 20%;height: 500px;background-color: #dddddd">{% menu_html request %}</div><div style="float: left;width: 80%">{% block content %}{% endblock %}</div><script src="/static/jquery-3.2.1.min.js"></script><script src="/static/rbac/rbac.js"></script></body> </html> View Code?
xxxxx.html:
{% for k,item in menu_dict.items %}<div class="item"><div class="item-title">{{ item.menu_title }}</div>{% if item.active %}<div class="item-permission">{% else %}<div class="item-permission hide">{% endif %}{% for v in item.children %}{% if v.active %}<a href="{{ v.url }}" class="active">{{ v.title }}</a>{% else %}<a href="{{ v.url }}">{{ v.title }}</a>{% endif %}{% endfor %}</div></div> {% endfor %} View Code?
轉載于:https://www.cnblogs.com/zhongbokun/p/8538862.html
總結
- 上一篇: bootstrap-fileinput上
- 下一篇: 关于深拷贝和浅拷贝