zoukankan      html  css  js  c++  java
  • 第五天.权限批量录入/更新、信号、Django日志配置

    1. 角色、菜单、权限的增删该查
            1. ModelForm增删改查
            2. 增加和编辑使用同一个视图函数
                Form()
                    1. 生成获取用户输入的标签
                    2. 对用户输入的内容做校验
                    3. 保留输入的内容同时展示错误提示信息
                ModelForm()
                    1. 不需要自己写类中字段
                    2. 编辑的时候可以使用instance参数直接把要修改的实例传到form表单
                        1. 生成获取用户输入的标签时能够把instance的属性直接当成默认值
                        2. POST提交的时候可以直接调用save()保存数据
                FormSet()
                    from django.forms import formset_factory
                ModelFormSet()
                    from django.forms import modelformset_factory
                
            
                ORM复习(对象关系映射)
                    1. 对应关系
                        ORM                        数据库
                        类            <-->          数据表
                        属性          <-->           字段
                        对象          <-->          数据行
        2. 爬取icon图标
            1. requests
            2. beautifulsoup4
        
        3. 权限批量录入
            1. 集合的操作
                1. 差集、交集、反交集
            2. 获取一个Django项目的所有路由
                rbac/utils/reload_routes.py
            3. 页面上将没有入库的路由数据直接加载到addformset中
            4. formset使用的三个要点
                1. {{ formsetobj.management_form }}      --> 管理form(提交数据的时候告诉后端我提交了多少条数据)
                2. 每一条数据中都要有form_obj.id(添加的时候不需要,编辑的时候需要)
                3. form表单的那三要素
    2. 今日内容
     权限的批量操作
            项目复杂之后URL有很多
            1. 自动根据项目的URL录入路由信息(能自动获取路由别名和URL)
                1. Django中的路由
                    二级路由 --> rbac:menu_list  #:号就是分割命名空间的,也就是rbacapp的urls.py中还可以再include包另外的路由
                    三级路由 --> rbac:menu:menu_list
            2. 自动录入写完之后会有三种情况:
                1. 权限表里有,项目里面没有
                2. 权限表里有,项目里面也有
                3. 权限表里没有,项目里面有--如加新功能app
        
            3. formset提交数据三要素
                1. form表单
                2. submit按钮
                3. formset_obj.management_form
            4. 因为使用的是Formset而不是ModelFormset所以不能调用save()保存,需要自己手动创建数据
    1. 批量录入权限2 1. formset和modelformset的使用 2. 集合的操作 3. 如何巧妙的区分同一个action两次不同的POST请求 2. jQuery中文文档:http://jquery.cuishifeng.cn/ 3. 批量更新权限 1. 页面实现 1. Bootstrap、jQuery 2. 页面更新 1. 两个form表单POST提交数据 永远都唔好低估自己! 不负此生,前程似锦!

    一.批量录入权限

      我想实现的是利用formset实现的是只要你访问某个url,就能把当前项目里所有的路由:第一部分项目里没有但权限表里没有的放在下图1新增中。第二部分是我权限表和项目里都有的,放在下图2更新权限中。第三部分是我数据库里有但项目里没有的,放在如下图3中,此三图在一个页面实现操作管理。

       

     

     (1)rbac/utils/reload_routes.py:自动录入脚本

    from django.conf import settings
    from django.utils.module_loading import import_string #module_loading是加载模块
    from django.urls import RegexURLResolver
    from collections import OrderedDict
    
    #per_namespae是前一个命名空间,pre_url是上一级路由,urlpatterns路由表达式,生成一字典
    def recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict):
        for item in urlpatterns:
            # 如果是嵌套的URL
            if isinstance(item, RegexURLResolver):
                if pre_namespace:
                    if item.namespace:
                    #如果是嵌套的路由那就拿上一级路由命名空间给它拼起来,如果没有上一级则不用拼接直接赋值
                        namespace = '{}:{}'.format(pre_namespace, item.namespace,)
                    else:
                        namespace = pre_namespace
                else:
                    if item.namespace:
                        namespace = item.namespace
                    else:
                        namespace = None
                # 如果还有嵌套的三级、四级...路由就递归的执行
                recursion_urls(namespace, pre_url + item.regex.pattern, item.url_patterns, url_ordered_dict)
            # 普通URL
            else:
                if pre_namespace:
                    name = '{}:{}'.format(pre_namespace, item.name,)
                else:
                    name = item.name
                if not item.name:
                    raise Exception('URL路由中必须设置name属性')
                url = pre_url + item.regex.pattern
                # 把分析出来的每一条路由都以 命名空间:路由别名 为key 存到有序字典里
                url_ordered_dict[name] = {'name': name, 'url': url.replace('^', '').replace('$', '')}
    
    
    def get_all_url_dict(ignore_namespace_list=None):#忽略命名空间的列表作为参数但它是可变类型所以设为none好
        """获取路由中"""
        ignore_list = ignore_namespace_list or []
        # 生成一个有序的字典
        url_ordered_dict = OrderedDict()
        # 导入Django的路由配置:import_string是根据一字符串导入的模块
        root_url_conf = import_string(settings.ROOT_URLCONF)
        # 生成一个空列表
        urlpatterns = []
        # for循环项目所有的路由--luffy_permission/urls.py中的所有路由列表--一级路由
        for item in root_url_conf.urlpatterns:
            #如果路由是regexurlresolver嵌套路由类型且命名空间在忽略的列表中就continue跳过这次循环
            if isinstance(item, RegexURLResolver) and item.namespace in ignore_list:
                continue
            urlpatterns.append(item)
        # 调用上方的函数分析并收集项目中的路由,None是pre_namespace参数(前一个命名空间--在django的路由里它可以嵌套好几层)
        recursion_urls(None, '/', urlpatterns, url_ordered_dict)
        return url_ordered_dict

    (2)rbac/urls.py中:

    #权限批量录入
    url(r'^permission_entry/$', views.permission_entry, name='permission_entry'),

    (3)rbac/views.py中:

    from rbac.utils import permission ,reload_routes
    from rbac.forms import RoleForm, MenuForm, PermissionForm
    from django.forms import modelform_factory, formset_factory
    
    # 权限录入
    def permission_entry(request):
        # 项目里面所有的路由--当你一访问permission_entry时调用get_all_dict方法
        all_urls = reload_routes.get_all_url_dict(ignore_namespace_list=['admin', ])
        # 数据库中权限表中存储的所有路由
        all_permissions = Permission.objects.all()
    
        # 用集合去判断
        # 项目中所有路由的集合
        project_url_set = set(all_urls.keys())
        # 数据库中permission表中的路由集合
        db_url_set = set([i.name for i in all_permissions])
        # 项目中有,数据库中没有
        only_in_project = project_url_set - db_url_set
        # 这些路由应该是等待添加到数据库中权限表里面的数据
        AddFormset = formset_factory(PermissionForm, extra=0)
        add_formset_obj = AddFormset(initial=[v for k, v in all_urls.items() if k in only_in_project])
        if request.method == 'POST':
            add_formset_obj = AddFormset(request.POST)
            if add_formset_obj.is_valid():
                # 手动创建permission
                objs = (Permission(**item) for item in add_formset_obj.cleaned_data)
                Permission.objects.bulk_create(objs)
                return redirect(reverse('rbac:permission_entry'))
        return render(
            request,
            'rbac/permission_entry.html',
            {'add_formset_obj': add_formset_obj}
        )

    (4)rbac/templates/rbac/permission_entry.html中:

      放三个小面板.

    {% extends 'layout.html' %}
    
    {% block content %}
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <form action="" method="post">
                    {% csrf_token %}
                        <div class="panel panel-default">
                        <div class="panel-heading">
                            <h3 class="panel-title">添加权限
                            <button class="btn btn-success btn-xs pull-right" type="submit">添加</button>
                            </h3>
                        </div>
                        <div class="panel-body">
                            <p>那些只在项目中,还没来得及太能加到permission表中的路由数据</p>
                            <table class="table table-bordered">
                                <thead>
                                <tr>
                                    <th>#</th>
                                    <th>title</th>
                                    <th>url</th>
                                    <th>show</th>
                                    <th>name</th>
                                    <th>menu</th>
                                </tr>
                                </thead>
                                <tbody>
                                {% for form_obj in add_formset_obj %}
                                    {{ add_formset_obj.management_form }}
                                    <tr>
                                        {{ form_obj.id }}
                                        <td>{{ forloop.counter }}</td>
                                        <td>{{ form_obj.title }} <span>{{ form_obj.title.errors.0 }}</span></td>
                                        <td>{{ form_obj.url }}</td>
                                        <td>{{ form_obj.show }}</td>
                                        <td>{{ form_obj.name }}</td>
                                        <td>{{ form_obj.menu }}</td>
                                    </tr>
                                {% endfor %}
    
                                </tbody>
                            </table>
                        </div>
                    </div>
                    </form>
                </div>
            </div>
        </div>
    {% endblock %}

    3

  • 相关阅读:
    Exchange 2013与 Office Web Apps 整合
    SharePoint2013 以其他用户登录和修改AD域用户密码 功能
    sharepoint 2010 自定义页面布局
    sharepoint 2010 记录管理 对象模型
    SharePoint2010 对象模型 关联列表
    在SharePoint Server 2010中更改“我的网站”
    xenapp 6.5 客户端插件第一次安装总是跳到官网
    如何解决在Windows Server 2008 R2 上安装证书服务重启后出现 CertificationAuthority 91错误事件
    在Win7 Hyper-v虚拟机中挂接真实机的声卡
    win8 中如何删除 共享文件夹 用户名和密码
  • 原文地址:https://www.cnblogs.com/dbslinux/p/12825321.html
Copyright © 2011-2022 走看看