对于权限表的操作有两种方式,第一种是一个个的权限进行curd,另外一种是批量操作,自动发现django程序中的路由,进行批量curd,首先介绍第一种方式。

因为在列出菜单时,已经将权限列表列出来了,所以权限包括增加、修改以及删除操作

urls.py

...
re_path(r'^permissions/add/$', PermissionAddView.as_view(), name='permissions_add'),
re_path(r'^permissions/edit/(?P<pid>\d+)/$', PermissionEditView.as_view(), name='permissions_edit'),
re_path(r'^permissions/dell/(?P<pid>\d+)/$', PermissionDelView.as_view(), name='permissions_del'),
re_path(r'^multi/permissions/$', multi_permissions, name='multi_permissions'),
...

后台进行处理

from django import forms
from rbac import models class PermissionModelForm(forms.ModelForm): class Meta:
model=models.Permission
fields='__all__' widgets = {
'title': forms.TextInput(attrs={'placeholder': '请输入权限名称', 'class': 'form-control'}),
'url': forms.TextInput(attrs={'placeholder': '请输入url', 'class': 'form-control'}),
'name': forms.TextInput(attrs={'placeholder': '请输入url名称', 'class': 'form-control'}),
'parent': forms.Select(attrs={'class': 'form-control'}),
'menu':forms.Select(attrs={'class': 'form-control'}),
}
help_texts={
'parent':'父级权限,无法作为菜单的权限才需要选择。',
'menu':'选中,表示该权限可以作为菜单;否则,不可做菜单。'
}
error_messages ={
'title':{
'required':'该字段不能为空'
}
} def clean(self):
menu=self.cleaned_data['menu']
parent=self.cleaned_data['parent']
if menu and parent:
self.add_error('menu','菜单和根权限同时只能选择一个')#错误标注在menu字段旁边

PermissionModelForm

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
from rbac.models import *
from rbac.forms.permissions import PermissionModelForm
from django.urls import reverse class PermissionAddView(View):
def get(self,request):
form = PermissionModelForm()
return render(request,'rbac/permission_add.html',{'form':form}) def post(self,request):
form=PermissionModelForm(data=request.POST)
if form.is_valid():
form.save()
return redirect(reverse('rbac:menus_list'))
return render(request,'rbac/permission_add.html',{'form':form}) class PermissionEditView(View): def get(self,request,pid):
permission_obj=Permission.objects.filter(id=pid).first()
if not permission_obj:
return HttpResponse('该权限不存在')
form=PermissionModelForm(instance=permission_obj)
return render(request,'rbac/permission_edit.html',{'form':form}) def post(self,request,pid):
permission_obj=Permission.objects.filter(id=pid).first()
form=PermissionModelForm(data=request.POST,instance=permission_obj)
if form.is_valid():
form.save()
return redirect(reverse('rbac:menus_list'))
return render(request, 'rbac/permission_edit.html', {'form': form}) class PermissionDelView(View): def get(self,request,pid):
Permission.objects.filter(id=pid).first().delete()
return redirect(reverse('rbac:menus_list'))

第二种方式是批量增加

class MultiPermissionForm(forms.Form):
id = forms.IntegerField(
widget=forms.HiddenInput(),
required=False
)
title = forms.CharField(
widget=forms.TextInput(attrs={'class': "form-control"})
)
url = forms.CharField(
widget=forms.TextInput(attrs={'class': "form-control"})
)
name = forms.CharField(
widget=forms.TextInput(attrs={'class': "form-control"})
)
menu_id = forms.ChoiceField(
choices=[(None, '-----')],
widget=forms.Select(attrs={'class': "form-control"}),
required=False, ) parent_id = forms.ChoiceField(
choices=[(None, '-----')],
widget=forms.Select(attrs={'class': "form-control"}),
required=False,
) def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['menu_id'].choices += models.Menu.objects.values_list('id', 'title')
self.fields['parent_id'].choices += models.Permission.objects.filter(parent__isnull=True).exclude(
menu__isnull=True).values_list('id', 'title') def clean_parent_id(self):
menu = self.cleaned_data.get('menu_id')
parent_id = self.cleaned_data.get('parent_id')
if menu and parent_id:
raise forms.ValidationError('菜单和根权限同时只能选择一个')
return parent_id

MultiPermissionForm

利用formset生成批量数据

from rbac.forms.muti_permissions import MultiPermissionForm
from django.shortcuts import render
from django.forms import formset_factory,modelform_factory
from rbac import models
from rbac.services.routes import * def multi_permissions(request):
"""
批量操作权限
:param request:
:return:
"""
post_type = request.GET.get('type') MultiPermissionFormSet = formset_factory(MultiPermissionForm,extra=0) generate_formset = None
update_formset = None if request.method == 'POST' and post_type == 'generate':
print('request.post',request.POST)
formset = MultiPermissionFormSet(request.POST)
if formset.is_valid():
for row_dict in formset.cleaned_data:
models.Permission.objects.create(**row_dict)
else:
generate_formset = formset if request.method == 'POST' and post_type == 'update':
formset = MultiPermissionFormSet(request.POST)
if formset.is_valid():
for row_dict in formset.cleaned_data:
permission_id = row_dict.pop('id')
models.Permission.objects.filter(id=permission_id).update(**row_dict)
else:
update_formset = formset # 1.1 去数据库中获取所有权限
# [{},{}]
permissions = models.Permission.objects.all().values('id', 'title', 'url', 'name', 'menu_id', 'parent_id')
# {'rbac:menu_list':{},'rbac:menu_add':{..}}
permisssion_dict = OrderedDict()
for per in permissions:
permisssion_dict[per['name']] = per # 1.2 数据库中有的所有权限name的集合
permission_name_set = set(permisssion_dict.keys()) # 2.1 获取路由系统中所有的URL
# {'rbac:menu_list':{'url':.... },,,}
router_dict = get_all_url_dict(ignore_namespace_list=['admin',]) for row in permissions:
name = row['name']
if name in router_dict:
router_dict[name].update(row) # 2.2 路由系统中的所有权限name的集合
router_name_set = set(router_dict.keys()) # 需要新建:数据库无、路由有
if not generate_formset:
generate_name_list=router_name_set-permission_name_set
generate_formset = MultiPermissionFormSet(
initial=[row for name, row in router_dict.items() if name in generate_name_list]
) # 需要删除:数据库有、路由无
destroy_name_list = permission_name_set - router_name_set
destroy_formset = [row for name, row in permisssion_dict.items() if name in destroy_name_list] # 需要更新:数据库有、路由有
if not update_formset:
update_name_list = permission_name_set.intersection(router_name_set)
update_formset = MultiPermissionFormSet(
initial=[row for name, row in router_dict.items() if name in update_name_list]
) return render(
request,
'rbac/multi_permissions.html',
{
'destroy_formset': destroy_formset,
'update_formset': update_formset,
'generate_formset': generate_formset,
}
)

获取路由系统中的url

import re
from collections import OrderedDict
from django.conf import settings
from django.utils.module_loading import import_string
from django.urls.resolvers import URLResolver, URLPattern def recursion_urls(pre_namespace, pre_url, valid_urlpattern_list, url_ordered_dict):
"""
递归的去获取URL
:param pre_namespace: namespace前缀,以后用户拼接name
:param pre_url: url前缀,以后用于拼接url
:param urlpatterns: 路由关系列表
:param url_ordered_dict: 用于保存递归中获取的所有路由
:return:
"""
for item in valid_urlpattern_list:
if isinstance(item, URLPattern): # 非路由分发,讲路由添加到url_ordered_dict
if not item.name:
continue
if pre_namespace:
name = "%s:%s" % (pre_namespace, item.name,)
else:
name = item.name
if not item.name:
raise Exception('URL路由中必须设置name属性')
url = pre_url + str(item.pattern)
url_ordered_dict[name] = {'name': name, 'url': url.replace('^', '').replace('$', '')} elif isinstance(item, URLResolver): # 路由分发,递归操作
if pre_namespace:
if item.namespace:
namespace = "%s:%s" % (pre_namespace, item.namespace,)
else:
namespace = pre_namespace
else:
if item.namespace:
namespace = item.namespace
else:
namespace = None
recursion_urls(namespace, pre_url + str(item.pattern), item.url_patterns, url_ordered_dict) def get_all_url_dict(ignore_namespace_list=None):
"""
获取项目中所有的URL(必须有name别名)
:return:
"""
ignore_namespace_list=ignore_namespace_list or []
valid_urlpattern_list=[]
url_ordered_dict = OrderedDict() urlpatterns_list= import_string(settings.ROOT_URLCONF).urlpatterns # from luff.. import urls for urlpattern in urlpatterns_list:
if isinstance(urlpattern, URLResolver):
if urlpattern.namespace in ignore_namespace_list:
continue
else:
valid_urlpattern_list.append(urlpattern)
valid_urlpattern_list.append(urlpattern) recursion_urls(None, '/', valid_urlpattern_list, url_ordered_dict) # 递归去获取所有的路由 return url_ordered_dict

rbac组件之权限操作(四)的更多相关文章

  1. rbac组件之角色操作(二)

    为了与stark组件分离,形成独立的模块,所以rbac数据表的操作需要单独进行操作,对角色表的操作. urls.py urlpatterns = [ re_path(r'^roles/list/$', ...

  2. rbac组件之菜单操作(三)

    菜单包括菜单列表,菜单列表不仅将菜单列出来,而且将每个菜单下的权限也列出来.菜单的添加.删除.修改. urls.py ... re_path(r'^menus/list/$', MenuView.as ...

  3. rbac组件之权限初始化(五)

    当用户登陆后,根据用户的角色要为用户生成对应的权限菜单,此时需要将登陆的用户信息获取且获取角色信息,从数据库中获取菜单以及权限信息,并且存入session中. 1.权限流程 第一次请求的页面是登陆页面 ...

  4. python 全栈开发,Day108(客户管理之权限控制,客户管理之动态"一级"菜单,其他应用使用rbac组件,django static文件的引入方式)

    一.客户管理之权限控制 昨天的作业,有很多不完善的地方 下载代码,基本实现权限验证 https://github.com/987334176/luffy_permission/archive/v1.2 ...

  5. DocX开源WORD操作组件的学习系列四

    DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...

  6. ThinkPHP中RBAC权限带菜单栏显示和详细权限操作

    RBAC是什么,能解决什么难题? RBAC是Role-Based Access Control的首字母,译成中文即基于角色的权限访问控制,说白了也就是用户通过角色与权限进行关联[其架构灵感来源于操作系 ...

  7. Linux学习之CentOS(四)----Linux文件属性、所有者、群组、其他组及文件权限操作简要总结

    Linux文件属性.所有者.群组.其他组及文件权限操作简要总结 首先介绍一个重要的知识点:文件属性控制权限 [root@www ~]# ls -al total 156 drwxr-x--- 4 ro ...

  8. rbac——界面、权限

    一.模板继承 知识点: users.html / roles.html 继承自 base.html 页面滚动时,固定 .menu { background-color: bisque; positio ...

  9. DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

随机推荐

  1. hdu 1044 Collect More Jewels

    题意: 一个n*m的迷宫,在t时刻后就会坍塌,问:在逃出来的前提下,能带出来多少价值的宝藏. 其中: ’*‘:代表墙壁: '.':代表道路: '@':代表起始位置: '<':代表出口: 'A'~ ...

  2. poj 3159 Candies dijkstra + queue

    题目链接: http://poj.org/searchproblem 题目大意: 飞天鼠是班长,一天班主任买了一大包糖果,要飞天鼠分发给大家,班里面有n个人,但是学生A认为学生B比自己多的糖果数目不应 ...

  3. webapp开发学习--Ionic+Cordova 环境搭建

    我们看 Ionic 能给我们提供什么? 一个样式库,你可以使用它来装饰你的HTML网页 ,看起来 想 移动程序的界面,什么header .content.footer.grid.list.这貌似没什么 ...

  4. ES6知识点汇总

    MDN镇楼: https://developer.mozilla.org/zh-CN/ 1.ES6新添加数据类型:symbol  -----------   https://developer.moz ...

  5. AJPFX总结面向对象思想设计原则

    面向对象思想设计原则   A.单一职责原则           其实就是开发人员经常说的”高内聚,低耦合”           也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原 ...

  6. poj3368 Frequent values

    思路: 转化为RMQ. 实现: #include <cstdio> #include <cstring> #include <algorithm> using na ...

  7. jquery 实现 点击把数据移动右侧 点击再次移回到左侧

    2018年第一发  希望新的一年和大家一下学习更多知识    JS://把数据左边挪到了右边,再从右边移动回来function moveOption(e1, e2){   $("#" ...

  8. Win10 1803更新UWP无法安装的解决办法|错误代码0x80073D0D

    升级Win10 1803后,出现了之前安装的UWP.应用无法更新,再此安装失败的现象. 应用商店错误代码为:0x80073D0D,尝试卸载重装商店,清除应用缓存也无法解决. 最终解决办法: 下载Eve ...

  9. jQuery 的DOM操作

    DOM创建节点及节点属性 创建元素:document.createElement设置属性:setAttribute添加文本:innerHTML加入文档:appendChild append()前面是被 ...

  10. 慎将MBTI测试用于招聘或就业:4星|《人格魅力修炼指南》

    人格魅力修炼指南:成为理想中的自己,就靠它了!(<哈佛商业评论>增刊) <哈佛商业评论>的11篇领导者人格魅力相关的文章.比较专业. 一些重要的信息:慎将MBTI测试用于“招聘 ...