rbac组件之权限操作(四)
对于权限表的操作有两种方式,第一种是一个个的权限进行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组件之权限操作(四)的更多相关文章
- rbac组件之角色操作(二)
为了与stark组件分离,形成独立的模块,所以rbac数据表的操作需要单独进行操作,对角色表的操作. urls.py urlpatterns = [ re_path(r'^roles/list/$', ...
- rbac组件之菜单操作(三)
菜单包括菜单列表,菜单列表不仅将菜单列出来,而且将每个菜单下的权限也列出来.菜单的添加.删除.修改. urls.py ... re_path(r'^menus/list/$', MenuView.as ...
- rbac组件之权限初始化(五)
当用户登陆后,根据用户的角色要为用户生成对应的权限菜单,此时需要将登陆的用户信息获取且获取角色信息,从数据库中获取菜单以及权限信息,并且存入session中. 1.权限流程 第一次请求的页面是登陆页面 ...
- python 全栈开发,Day108(客户管理之权限控制,客户管理之动态"一级"菜单,其他应用使用rbac组件,django static文件的引入方式)
一.客户管理之权限控制 昨天的作业,有很多不完善的地方 下载代码,基本实现权限验证 https://github.com/987334176/luffy_permission/archive/v1.2 ...
- DocX开源WORD操作组件的学习系列四
DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...
- ThinkPHP中RBAC权限带菜单栏显示和详细权限操作
RBAC是什么,能解决什么难题? RBAC是Role-Based Access Control的首字母,译成中文即基于角色的权限访问控制,说白了也就是用户通过角色与权限进行关联[其架构灵感来源于操作系 ...
- Linux学习之CentOS(四)----Linux文件属性、所有者、群组、其他组及文件权限操作简要总结
Linux文件属性.所有者.群组.其他组及文件权限操作简要总结 首先介绍一个重要的知识点:文件属性控制权限 [root@www ~]# ls -al total 156 drwxr-x--- 4 ro ...
- rbac——界面、权限
一.模板继承 知识点: users.html / roles.html 继承自 base.html 页面滚动时,固定 .menu { background-color: bisque; positio ...
- DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件
DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件 本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...
随机推荐
- 一条SQL语句是如何执行的?--Mysql45讲笔记记录 打卡day1
写在前面的话:回想以前上班的时候,空闲时间还是挺多的,但是都荒废了.如今找工作着实费劲了.但是这段时间在极客时间买了mysql45讲,就好像发现了新大陆一样,这是我认真做笔记的第一天,说实话第一讲我已 ...
- _bzoj1003 [ZJOI2006]物流运输【预处理】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1003 预处理出第i天到第j天走一条航线时的最短路. #include <cstdio& ...
- Android 线程池系列教程(3) 创建线程池
Creating a Manager for Multiple Threads 上一课 下一课 1.This lesson teaches you to Define the Thread Pool ...
- XmlPullParser接口详述
带*的是非常重要的函数.点击有说明.setInputgetDepthisWhitespacegetTextisEmptyElementTaggetAttributeCountgetAttributeV ...
- 事件模型的介绍与Button的ActionListener
事件监听: 这是个很重要的概念,也是个很重要的模型,vb,vc都是这样用,甚至后面学的web框架也在用. 现在我们可以做很多按钮了吧,但是我们的按钮按它是没反应的,现在我们来看看怎么样才能让它有 ...
- 转】RMySQL数据库编程指南
原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/page/2/ 感谢! Posted: Sep 24, 2013 Ta ...
- negroni-gzip源码简单分析解读
negroni-gzip源码简单分析解读 这是一个为Negroni设计的gzip压缩处理中间件,需要用到已有的compress中的gzip,阅读了不长的源码之后,总结了一些关键要点和注意点. 检查是否 ...
- Linux 之 2>&1
我们在Linux下经常会碰到nohup command>/dev/null 2>&1 &这样形式的命令.首先我们把这条命令大概分解下首先就是一个nohup表示当前用户和系统 ...
- 学习笔记 第九章 使用CSS美化表格
第9章 使用CSS美化表格 学习重点 正确使用表格标签: 设置表格和单元格属性: 设计表格的CSS样式. 9.1 表格的基本结构 表格由行.列.单元格3部分组成,单元格时行与列交叉的部分. 在HTM ...
- ASP.NET中调用事务处理的方法
/// <summary> /// 事务处理 /// </summary> /// <param name="strSql"></para ...