博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
权限组件(13):批量操作权限页面的展示和增删改查
阅读量:6287 次
发布时间:2019-06-22

本文共 12909 字,大约阅读时间需要 43 分钟。

效果图:

 

一、路由配置

rbac/urls.py

配置一个批量操作页面的路由和删除权限的路由

...from django.urls import re_pathfrom rbac.views import menu...urlpatterns = [    ...    # 批量操作权限    re_path(r'^multi/permissions/$', menu.multi_permissions, name='multi_permissions'),  # 自动发现项目中的所有URL    re_path(r'^multi/permissions/delete/(?P
\d+)', menu.multi_permissions_delete, name='multi_permissions_delete') ...]

 

 

二、forms表单验证

rbac/forms/menu.py

...from django import forms......class MultiAddPermissionForm(forms.Form):    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 ) pid_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.all().values_list('id', 'title') self.fields['pid_id'].choices += models.Permission.objects.filter(pid__isnull=True).exclude( menu__isnull=True).values_list('id', 'title')class MultiEditPermissionForm(forms.Form): id = forms.IntegerField( widget=forms.HiddenInput() ) # 获取用户id,进行修改操作 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 ) pid_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['pid_id'].choices += models.Permission.objects.filter(pid__isnull=True).exclude( menu__isnull=True).values_list('id', 'title') # 是二级菜单,不能没有一级菜...

 

 

三、视图函数

rbac/views/menu.py

... from django.forms.models import formset_factory ...
def multi_permissions(request):    """    批量操作权限    :param request:    :return:    """    post_type = request.GET.get('type')    generate_formset_class = formset_factory(MultiAddPermissionForm, extra=0)    update_formset_class = formset_factory(MultiEditPermissionForm, extra=0)    generate_formset = None  # 出错了赋值,为了返回给页面错误信息    update_formset = None  # 出错了赋值,为了返回给页面错误信息    # 批量添加    if request.method == 'POST' and post_type == 'generate':        formset = generate_formset_class(data=request.POST)  # 储存的所有信息,包括html标签        if formset.is_valid():            has_repeat_error = False            permission_obj_list = []            url_form_list = formset.cleaned_data            for num in range(0, formset.total_form_count()):                url_form = url_form_list[num]                # 下面的方式和model.Permission.object.create(**row)效果一样,这里用这种方式是为了捕获唯一性错误                try:                    permission_obj = models.Permission(**url_form)                    permission_obj.validate_unique()  # 检查当前对象在数据库是否存在唯一的                    permission_obj_list.append(permission_obj)                except Exception as e:                    formset.errors[num].update(e)  # 把错误信息放到对应的form里面                    generate_formset = formset  # 要把用户批量增加时出错的错误信息传给模板                    has_repeat_error = True            if not has_repeat_error:                models.Permission.objects.bulk_create(permission_obj_list, batch_size=formset.total_form_count())        else:            generate_formset = formset  # 出错信息传给模板    # 批量更新    if request.method == 'POST' and post_type == 'update':        formset = update_formset_class(data=request.POST)        if formset.is_valid():            url_form_list = formset.cleaned_data            for num in range(0, formset.total_form_count()):                url_form = url_form_list[num]                permission_id = url_form.pop('id')                try:                    permission_obj = models.Permission.objects.filter(id=permission_id).first()                    for key, value in url_form.items():                        setattr(permission_obj, key, value)                        permission_obj.validate_unique()                        permission_obj.save()                except Exception as e:                    formset.errors[num].update(e)                    update_formset = formset  # 要把用户批量更新时出错的错误信息传给模板        else:            update_formset = formset  # 出错信息传给模板    # 1. 获取项目中所有的url    all_url_dict = get_all_url_dict()    router_name_set = set(all_url_dict.keys())  # 所有路由中的url集合    """    set里不能有重复的值,转换成set后只会剩下key     {     'rbac:menu_list': {'name': 'rbac:menu_list', 'url': 'xxxxx/yyyy/menu/list'}     }      会变成 {'rbac:menu_list'}    """    #    # 2. 获取数据库中所有的url    all_db_permissions = models.Permission.objects.all().values('id', 'title', 'name', 'url', 'menu_id', 'pid_id')    db_permission_name_set = set()  # 数据库中的set集合    db_permission_dict = OrderedDict()    for db_permission in all_db_permissions:        db_permission_dict[db_permission[            'name']] = db_permission  # {'rbac:menu_list':{'id':1,'title':'角色列表',name:'rbac:role_list',url:'/rbac/role/list'},}        db_permission_name_set.add(db_permission['name'])  # {'rbac:menu_list','rbac:menu_add'......}    for name, value in db_permission_dict.items():        router_row_dict = all_url_dict.get(name)  # {'name':'rbac:role_list','url':'/rbac/role/list'},        if not router_row_dict:  # 没有别名和url的直接跳过            continue        if value['url'] != router_row_dict['url']:  # 数据库里的url和自动发现的url进行对比            value['url'] = '路由和数据库中的不一致'    # 3. 应该添加、删除和修改的权限    # 3.1 计算出应该添加的name    if not generate_formset:        """        如果目标没有通过验证,generate_formset的值就是上面出错了的formset,就不会执行下面的代码,页面就会显示错误信息        如果通过验证,就会返回给页面自动发现的数据库中有、路由中没有的url。        下面的 if not update_formset同理        """        generate_name_list = router_name_set - db_permission_name_set        generate_formset = generate_formset_class(            initial=[add_url for name, add_url in all_url_dict.items() if name in generate_name_list]        )    # 3.2 计算出应该删除的name : 数据库有,路由中没有    delete_url_name_list = db_permission_name_set - router_name_set  # 数据库里的url - 路由中的url    delete_url_list = [delete_url_obj for name, delete_url_obj in db_permission_dict.items() if name in delete_url_name_list]    # 3.3 计算出应该更新的name :数据库和路由中都有    if not update_formset:        update_name_list = db_permission_name_set & router_name_set  # 都包含的元素        update_formset = update_formset_class(            initial=[update_url for name, update_url in db_permission_dict.items() if name in update_name_list]        )    context = {        'generate_formset': generate_formset,        'delete_url_list': delete_url_list,        'update_formset': update_formset,    }    return render(request, 'rbac/multi_permissions.html', context)def multi_permissions_delete(request, pk):    """    批量页面的权限删除    :param request:    :param pk:    :return:    """    multi_pemrission_url = memory_reverse(request, 'rbac:multi_permissions')    if request.method == 'GET':        return render(request, 'rbac/delete.html', {
'cancel': multi_pemrission_url}) models.Permission.objects.filter(id=pk).delete() return redirect(multi_pemrission_url)

 

 

四、模板

rbac/templates/multi_permissions.html

{% extends 'layout.html' %}{% block content %}    
{% csrf_token %} {
{ generate_formset.management_form }}
{% for form in generate_formset %}
{% for field in form %}
{% endfor %}
{% endfor %}
序号 名称 URL 别名 菜单 父权限
{ { forloop.counter }} { { field }} { { field.errors.0 }}
{% for delete_url_obj in delete_url_list %}
{% endfor %}
序号 名称 URL 别名 删除
{ { forloop.counter }} { { delete_url_obj.title }} { { delete_url_obj.url }} { { delete_url_obj.name }}
{% csrf_token %} {
{ update_formset.management_form }}
{% for form in update_formset %}
{% for field in form %} {% if forloop.first %} { { field }} {% else %}
{% endif %} {% endfor %}
{% endfor %}
序号 名称 URL 别名 菜单 父权限
{ { forloop.counter }} { { field }} { { field.errors.0 }}
{% endblock content %}

 

 

在rbac/templates/menu_list.html的权限表里加上批量操作权限的按钮

{% extends 'layout.html' %}{% load rbac %}{% block css %}    {% endblock css %}{% block content %}    
{% for menu in menus %}
{% endfor %}
名称 图标 选项
{% if menu_id %}
{% endif %}
{% for second_menu in second_menus %}
{% endfor %}
名称 CODE&URL 选项
{ { second_menu.title }} { { second_menu.name }}
{ { second_menu.url }}
{% if second_menu_id %}
{% endif %}
{% for permission in permissions %}
{% endfor %}
名称 CODE&URL 选项
{ { permission.title }} { { permission.name }}
{ { permission.url }}
{% endblock content %}

 

转载于:https://www.cnblogs.com/lshedward/p/10528580.html

你可能感兴趣的文章
《ArcGIS Runtime SDK for Android开发笔记》——问题集:如何解决ArcGIS Runtime SDK for Android中文标注无法显示的问题(转载)...
查看>>
Spring Boot日志管理
查看>>
动态注册HttpModule管道,实现global.asax功能
查看>>
使用 ES2015 编写 Gulp 构建
查看>>
[转]Using NLog for ASP.NET Core to write custom information to the database
查看>>
BZOJ 4766: 文艺计算姬 [矩阵树定理 快速乘]
查看>>
MySQL 的instr函数
查看>>
Hibernate的核心对象关系映射
查看>>
接口与抽象类的使用选择
查看>>
if __name__ == '__main__'
查看>>
CF 375D. Tree and Queries【莫队 | dsu on tree】
查看>>
Maven最佳实践 划分模块 配置多模块项目 pom modules
查看>>
Hadoop学习笔记——WordCount
查看>>
Unity应用架构设计(4)——设计可复用的SubView和SubViewModel(Part 1)
查看>>
Java-Spring-获取Request,Response对象
查看>>
opencv项目报错_pFirstBlock==pHead解决办法
查看>>
MySQL日志
查看>>
Oracle性能优化之Oracle里的执行计划
查看>>
电脑如何连接远程服务器?听语音
查看>>
使用Xcode 查看objective-C的汇编代码
查看>>