当前位置: 首页 > news >正文

DRF-(10)

内容概览

  • 排序和过滤源码分析
  • 基于jwt的认证类
  • RBAC的介绍和使用
  • 后台管理simpleUI的介绍和使用

排序和过滤源码分析

"""
继承了GenericAPIView和ListModelMixin,只要在视图类中配置filter_backends就能够实现过滤与排序
1. drf内置的过滤类(SearchFilter),排序类(OrderingFilter)
2. 第三方模块django-filter
3. 自定义过滤排序类:继承BaseFilterBackend,重写filter_queryset,返回过滤或排序后的queryset对象
"""

"""只有获取所有数据才需要使用排序,所以应该查看list方法中的代码"""
# list方法
    def list(self, request, *args, **kwargs):
        # self.get_queryset()所有数据,经过了self.filter_queryset返回了queryset对象
        # self.filter_queryset完成的过滤
        queryset = self.filter_queryset(self.get_queryset())
        # 如果有分页,走的分页----》视图类中配置了分页类
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
	   # 如果没有分页,走正常的序列化,返回
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
    
    
# self.filter_queryset完成了过滤,当前在视图类中,self是视图类的对象,去视图类中找没找到,去父类---》GenericAPIView---》filter_queryset
    
        def filter_queryset(self, queryset):
            for backend in list(self.filter_backends):  # 循环获取我们配置的过滤类
                queryset = backend().filter_queryset(self.request, queryset, self)  # 执行过滤类中的filter._queryset方法过滤数据
            return queryset

"""
总结:
	1. 写过滤类要重写filter_queryset方法,返回过滤或排序后的queryset对象
	2. 如果不想写过滤类,因为调用的是父类GenericAPIView中的filter_queryset方法,所以可以直接在视图类中重写filter_queryset方法,在方法中过滤或排序后返回queryset对象即可
"""

基于jwt的认证类

class JWTAuthentication(BaseAuthentication):
    def authenticate(self, request):
        jwt_value = request.META.get('HTTP_TOKEN')  # 自定义token发送到后端的方式
        # 验证token是否合法,jwt模块下一定有个验证token的函数
        try:
            payload = jwt_decode_handler(jwt_value)
        except jwt.ExpiredSignature:
            raise AuthenticationFailed('token过期了')
        except jwt.DecodeError:
            raise AuthenticationFailed('token解码失败')
        except jwt.InvalidTokenError:
            raise AuthenticationFailed('认证失败')
        # 执行到这,说明token合法,payload可以使用
        user = UserInfo.objects.filter(pk=user_id).first()  # 每次都要查数据库,效率不太好
        return (user, jwt_value)
        # return (payload,jwt_value)  # 可以返回paylod,包含用户姓名与id,可以在需要的时候从request.user.get()获取,不用每次查数据库

RBAC的介绍和使用

  • RBAC(Role-Based Access Control )是基于角色的访问控制
    在 RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。
    这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便
    RBAC权限管理的模式,适用于公司内部的管理系统,不适合用于对外互联网的系统
    用户:用户表
    角色(部门):角色(部门)表
    权限:权限表
    所有权限都记录在权限表中,通过多对多的方式给各个角色分配权限
    用户表中的用户,通过多对多的方式关联角色表,得到各自角色所拥有的权限
    所以一共有5张表:用户表,角色表,权限表,用户与角色关联表,角色与权限关联表

  • django的后台管理admin自带了RBAC的权限管理,通过auth模块实现,不过比普通RBAC多了一个功能
    django额外在用户与权限之间开设了多对多的关系表
    在用户需要一些权限,通过角色获取的权限又太多了的情况下,就可以单独给用户开设权限
    启用了admin与auth迁移表时,这6张表就迁移进去了
    auth_user:用户表
    auth_group:角色,组,部门表
    auth_permission:权限表
    auth_user_groups:用户和角色中间表
    auth_group_permissions:角色跟权限中间表
    auth_user_user_permissions:用户和权限的中间表

ACL、RBAC、ABAC(PBAC/CBAC)权限控制的介绍

"""ACL(Access Control List,访问控制列表)"""
将用户或组直接与对象的权限对接:用户表,权限表,中间表;

"""RBAC(Role-Based Access Control,基于角色的访问控制)"""
将用户与角色对接,然后角色与对象的权限对接将用户与角色对接,然后角色与对象的权限对接

"""RBAC+ACL,django使用,公司用的较多"""

"""
ABAC(Attribute-Based Access Control,基于属性的访问控制)
又称为PBAC(Policy-Based Access Control,基于策略的访问控制)
CBAC(Claims-Based Access Control,基于声明的访问控制)
"""

传统的ACL、RBAC的架构是
{subject,action,object},
而ABAC的架构是
{subject,action,object,contextual}且为他们添加了parameter(参数)。

subject属性:比如用户的年龄、部门、角色、威望、积分等主题属性。

action属性:比如查看、读取、编辑、删除等行为属性。

object属性:比如银行账户、文章、评论等对象或资源属性。

contextual属性:比如时段、IP位置、天气等环境属性。

casbin:方便快速的做权限控制

import casbin

e = casbin.Enforcer("./model.conf", "./policy.csv")

sub = "lqz"  # 想要访问资源的用户
obj = "book"  # 将要被访问的资源
act = "get"  # 用户对资源进行的操作


# 自己写acl的控制
# 当前用户id,去权限和用户表查询即可,有记录就是有权限

# 自己写rbac
# 当前用户id,找到他的角色,根据角色拿出权限,判断当前访问有没有


if e.enforce(sub, obj, act):
    # 允许alice读取data1
    print('有权限')
    return True
else:
    # 拒绝请求,抛出异常
    print('没有权限')
    return False

model.conf

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

policy.csv

p,alice,data1,read
p,bob,data2,write
p,lqz,book,get

后台管理simpleUI的介绍与使用

Simple UI文档

"""
django admin自带了权限控制,但是是前后端混合,我们可以二次开发,开发出公司内部的自动化运行,自动化测试等;但是默认界面的样式不太好看
对django admin进行美化
xadmin(不用了,过时了)
simpleui(正红)
"""

# 1. 下载第三方模块
pip install django-simpleui

# 2. 注册app(放在第一位)
INSTALLED_APPS = [
    'simpleui',
    'django.contrib.admin',
    'django.contrib.auth',
	...
]

"""配置完成后后台管理样式就已经改变了"""

自定义菜单

settings.py

import time
SIMPLEUI_CONFIG = {
    'system_keep': False,  # 该字段用于告诉simpleui,是否需要保留系统默认的菜单,默认为False,不保留。 如果改为True,自定义和系统菜单将会并存
    'menu_display': ['我的首页','图书管理','权限认证', '多级菜单测试', '动态菜单测试'],      # 开启排序和过滤功能, 不填此字段为默认排序和全部显示, 空列表[] 为全部不显示.
    'dynamic': True,    # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
    'menus': [{
        'name': '我的首页',
        'icon': 'fas fa-code',
        'url': '/index/',
        # 浏览器新标签中打开
        'newTab': True,
    },
    {
            'app': 'app01',
            'name': '图书管理',
            'icon': 'fas fa-code',
            'models': [
                {
                    'name': '用户',
                    'icon': 'fa fa-user',
                    'url': 'app01/userinfo/'
                },
                {
                    'name': '图书',
                    'icon': 'fa fa-user',
                    'url': 'app01/book/'
                },
                {
                    'name': '出版社',
                    'icon': 'fa fa-user',
                    'url': 'app01/publish/'
                },
            ]
        },
     {
        'app': 'auth',
        'name': '权限认证',
        'icon': 'fas fa-user-shield',
        'models': [{
            'name': '用户',
            'icon': 'fa fa-user',
            'url': 'auth/user/'
        }]
    }, {
        # 自2021.02.01+ 支持多级菜单,models 为子菜单名
        'name': '多级菜单测试',
        'icon': 'fa fa-file',
      	# 二级菜单
        'models': [{
            'name': 'Baidu',
            'icon': 'far fa-surprise',
            # 第三级菜单 ,
            'models': [
                {
                  'name': '爱奇艺',
                  'url': 'https://www.iqiyi.com/dianshiju/'
                  # 第四级就不支持了,element只支持了3级
                }, {
                    'name': '百度问答',
                    'icon': 'far fa-surprise',
                    'url': 'https://zhidao.baidu.com/'
                }
            ]
        }]
    }, {
        'name': '动态菜单测试' ,
        'icon': 'fa fa-desktop',
        'models': [{
            'name': time.time(),
            'url': 'http://baidu.com',
            'icon': 'far fa-surprise'
        }]
    }]
}


"""配置"""
SIMPLEUI_LOGIN_PARTICLES = False  # 关闭登录页面粒子动画
SIMPLEUI_HOME_INFO = False  # 是否显示服务器信息

自定义按钮

admin.py

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'price')  # 表中的字段

    # 增加自定义按钮
    actions = ['make_copy', ]
    def make_copy(self, request, queryset):
        print('adsfasdf')  # 点击按钮触发的事件
    make_copy.short_description = '自定义按钮'  # 按钮显示的文本
    # # icon,参考element-ui icon与https://fontawesome.com
    make_copy.icon = 'fas fa-audio-description'
    # # 指定element-ui的按钮类型,参考https://element.eleme.cn/#/zh-CN/component/button
    make_copy.type = 'danger'
    make_copy.confirm = '你是否执意要点击这个按钮?'

相关文章:

  • java面试-GC垃圾回收机制
  • TOREX | 如何延长设备的电池寿命?——充电IC
  • 电路方案分析(十一)低电平(5uA)V-I转化器
  • 【Hadoop生态圈】8.Flink入门教程
  • 代码整洁之道,评审问题分享记录
  • 【调研】详解Transformer结构——Attention Is All You Need
  • Linux基础组件之消息协议设计概述
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • 微服务Spring Boot 整合 Redis 分布式锁 Redission 实现优惠卷秒杀 一人一单
  • java毕业设计医护人员排班系统Mybatis+系统+数据库+调试部署
  • 分库分表实战之从根上带你吃透MySQL的索引
  • 学习大数据环境搭建
  • STM32——SD卡实验(SDIO方式)
  • JavaWeb(部分)
  • 还在盲目内卷?腾讯强推Spring Security 速成笔记,认证授权一键拿下
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 【笔记】你不知道的JS读书笔记——Promise
  • CentOS6 编译安装 redis-3.2.3
  • gf框架之分页模块(五) - 自定义分页
  • IDEA常用插件整理
  • JavaScript 基础知识 - 入门篇(一)
  • Markdown 语法简单说明
  • nodejs实现webservice问题总结
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • spring学习第二天
  • SSH 免密登录
  • webpack4 一点通
  • 关于 Cirru Editor 存储格式
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 巧用 TypeScript (一)
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 数据可视化之 Sankey 桑基图的实现
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 用element的upload组件实现多图片上传和压缩
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • #define、const、typedef的差别
  • #Z0458. 树的中心2
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (11)MATLAB PCA+SVM 人脸识别
  • (rabbitmq的高级特性)消息可靠性
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (二)丶RabbitMQ的六大核心
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (四)Controller接口控制器详解(三)
  • (一)VirtualBox安装增强功能
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .net core 依赖注入的基本用发
  • .net 设置默认首页