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注册器 五 响应器 六 分 ...
随机推荐
- 【插件开发】—— 8 IPreferenceStore,插件的键/值存储!
前文回顾: 1 插件学习篇 2 简单的建立插件工程以及模型文件分析 3 利用扩展点,开发透视图 4 SWT编程须知 5 SWT简单控件的使用与布局搭配 6 SWT复杂空间与布局搭配 7 SWT布局详解 ...
- css覆盖select样式并添加小箭头
.select { border-radius: 5px; border: 1px #F4A627 solid; -webkit-appearance: none;//清除默认样式 backgroun ...
- Python学习规划
短时间踏实而高效的学习python 知乎:如何系统的学习python 简书:最全的python学习手册 目录 Python编程语言 python视频教程 Python神经网络算法与深度学习视频教程人工 ...
- 题解报告:hdu 2062 Subset sequence
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2062 Problem Description 考虑集合An = {1,2,...,n}. 例如,A1 ...
- python general
everything in python is object assignment is binding a name to an object one object can have several ...
- 转】Mahout构建图书推荐系统
原博文出自于: http://blog.fens.me/hadoop-mahout-recommend-book/ 感谢! Mahout构建图书推荐系统 Hadoop家族系列文章,主要介绍Hadoop ...
- jquery 实现 点击把数据移动右侧 点击再次移回到左侧
2018年第一发 希望新的一年和大家一下学习更多知识 JS://把数据左边挪到了右边,再从右边移动回来function moveOption(e1, e2){ $("#" ...
- iOS Cell异步图片加载优化,缓存机制详解
最近研究了一下UITbleView中异步加载网络图片的问题,iOS应用经常会看到这种界面.一个tableView上显示一些标题.详情等内容,在加上一张图片.这里说一下这种思路. 为了防止图片多次下载, ...
- 迅为工业级arm开发板i.MX6DL开发板软件硬件全开源
i.MX6是基于ARM Cortex™-A9架构的高扩展性多核系列应用处理器,促进了如高稳定性工业平板电脑.差异化智能本.前装车载中控系统和超高清电子书阅读器等新一代应用的发展.强劲的3D图形加速引擎 ...
- cp - 复制文件和目录
总览 cp [选项] 文件路径 cp [选项] 文件...目录 POSIX 选项: [-fipRr] GNU 参数(最短形式): [-abdfilprsuvxPR] [-S SUFFIX] [-V { ...