对于权限表的操作有两种方式,第一种是一个个的权限进行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. 洛谷P3261 [JLOI2015]城池攻占(左偏树)

    传送门 每一个城市代表的点开一个小根堆,把每一个骑士合并到它开始攻占的城池所代表的点上 然后开始dfs,每一次把子树里那些还活着的骑士合并上来 然后再考虑当前点的堆,一直pop直到骑士全死光或者剩下的 ...

  2. 【练习】Java实现的杨辉三角形控制台输出

    import java.util.Scanner; /** * YangHui_tst01 * @author HmLy * @version 000 * - - - - - - - * 练习代码.( ...

  3. USACO Training刷题记录 By cellur925

    Section 1.1 Your Ride Is Here 貌似没啥可说 Greedy Gift Givers 上来就想stl map映射,有两个坑:如果送给别人的人数为0,那么需要特判一下,防止整数 ...

  4. Logstash读取文本信息并写入到ES

    Logstash读取文本信息并写入到ES 前提是ELK安装没问题 进入到logstash安装目录下的bin目录(我的logstash安装目录:/usr/local/) [root@es1 bin]# ...

  5. mybatis 批量insert,update报错 The error occurred while setting parameters

    数据脚本执行正常,但是报错,搜索关键信息 The error occurred while setting parameters ,发现了解决帖子: http://blog.csdn.net/jing ...

  6. TCP/IP网络协议基础

    实验楼学习网络协议传送门 一.TCP/IP简介 TCP/IP(Transmission Control Protocol/Internet Protocol)是传输控制协议和网络协议的简称,它定义了电 ...

  7. 209 Minimum Size Subarray Sum 大于给定和最短子数组

    给定一个含有 n 个正整数的数组和一个正整数 s , 找到一个最小的连续子数组的长度,使得这个子数组的数字和 ≥  s .如果不存在符合条件的子数组,返回 0.举个例子,给定数组 [2,3,1,2,4 ...

  8. 安装Kube

    安装Docker yum install -y docker 加速Docker DOCKER_MIRRORS="https://5md0553g.mirror.aliyuncs.com&qu ...

  9. ural1437

    1437 记忆化 模拟倒水过程 #include <iostream> #include<cstdio> #include<cstring> #include< ...

  10. XML To Linq 读取Sharepoint列表中的附件列信息

    通过页面查看,列表附件信息列的内容如下: var x = @"<div class='ExternalClass9936DCD1F074427B891D09CFCEFC2AB6'> ...