DRFday09-DRF‑Day09 权限、全套知识点复盘 & 序列化源码阅读

一、权限体系介绍

1.1 三种权限模型

  1. ACL 访问控制列表

用户 ↔ 权限,多对多。直接给用户分配权限。

  • 用户表、权限表、用户‑权限中间表
  • 例子:张三拥有【开直播、评论】权限
  1. RBAC 基于角色的访问控制(企业内部系统最常用)

用户 → 角色 → 权限

  • 用户表、角色表、权限表
  • 用户和角色多对多;角色和权限多对多
  • 示例:张三【总裁】角色,总裁拥有【开总裁会、发工资】权限
  1. ABAC 基于属性的访问控制

根据用户、环境、资源属性做判断,策略化权限。

1.2 Django Admin 的权限(RBAC+ACL混合)

Django 内置6张权限表:

  1. 用户表
  2. 组表(角色)
  3. 权限表(每张模型表自动生成增删改查4个权限)
  4. 用户‑组中间表(RBAC:用户分配角色)
  5. 组‑权限中间表(RBAC:角色分配权限)
  6. 用户‑权限中间表(ACL:直接给用户加权限)

admin底层就是这套;很多后台管理框架:django‑vue‑admin、若依(Java)、gin‑admin(Go)都是这套思想。


二、DRF 整体大回顾

2.1 开发模式 & REST规范

  1. 前后端混合 / 前后端分离
  2. API接口:前后端交互入口
  3. 测试工具:Postman、Apifox、HiFox
  4. RESTful接口规范(10条)
  5. DRF快速实现5个接口:查全部、查单条、新增、删除、修改
    • 序列化类:ModelSerializer
    • 路由:SimpleRouter自动生成路由
    • 视图:ModelViewSet

Request对象

  • request.data:POST/PUT提交的数据(解析json、form)
  • request.query_params:url问号后面的参数,等价于request.GET
  • request._request:原生django request对象

APIView执行完整流程

  1. 包装原生request,生成DRF新Request对象
  2. 执行三大认证:认证类 → 权限类 → 频率类
  3. 全局异常捕获处理
  4. 关闭CSRF校验

2.2 序列化模块

序列化三件事:序列化、反序列化、数据校验

  1. 基础继承 serializers.Serializer
# 序列化(对象→json)
ser = BookSerializer(instance=obj, many=True)
ser.data

# 反序列化(json→模型对象)
ser = BookSerializer(data=request.data)
ser.is_valid()
ser.save() # 调用序列化类create / update

Serializer 需要自己重写create()、update();ModelSerializer不需要。

  1. 常用字段:CharField、IntegerField、ListField、DictField
  2. 字段参数:max_length、required、default、read_only、write_only
  3. 校验三层:
    • 字段本身校验
    • 局部钩子 validate_字段名
    • 全局钩子 validate(self,attrs)
  4. 定制返回数据4种手段
    • source
    • 模型表写自定义方法
    • SerializerMethodField,搭配get_xxx方法
    • 子序列化(嵌套序列化)
  5. ModelSerializer
class Meta:
    model = 模型
    fields = ["id","name"]
    extra_kwargs = {"name":{"required":True}}

密码注意:不要直接create(password=xxx),要用create_user()做密码加密存储。

  1. 多表关联序列化&反序列化

2.3 请求与响应

  1. Request自动解析多种编码格式,支持全局、局部配置解析器,也可以局部禁用。
  2. Response(data, status, headers)
    • data:字典、列表、字符串
    • status:http状态码200/400/401等
    • headers:自定义响应头

2.4 视图层

  1. 两个基类
  • APIView:DRF最顶层视图
  • GenericAPIView:封装了queryset、serializer_class;提供get_object()、get_serializer()、get_queryset()
  1. 5个视图扩展类(mixin),必须搭配GenericAPIView
    ListModelMixin、CreateModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin

  2. 9个视图子类:GenericAPIView + mixin组合,直接写get/post即可。

  3. 视图集

  • GenericViewSet
  • ModelViewSet:增删改查全套
  • ReadOnlyModelViewSet:只读(查全部、查单条)
  • ViewSetMixin:改变路由映射方式,才有action属性

self.action:只有继承ViewSetMixin的视图集才有,可以拿到当前执行动作list/create/retrieve/update/destroy

2.5 路由层

  1. 手动映射(ViewSet专用)
path("books/", BookView.as_view({"post":"create","get":"list"}))
  1. SimpleRouter自动生成路由
router = SimpleRouter()
router.register("books",views.BookView)
urlpatterns += router.urls
  1. @action装饰器:自定义接口,methods指定请求方式,detail=True/False控制是否带pk。

2.6 三大认证(APIView核心流程)

执行顺序:认证类 → 权限类 → 频率类

  1. 认证类 Authenticaton
    作用:识别当前是谁在访问,解析token/session,得到request.user
  • 局部配置、全局配置、局部禁用
  • 重写authenticate(self,request),返回元组(user,凭证)
  1. 权限类 Permission

用户已经识别完成,判断这个用户有没有资格执行这个接口。
重写has_permission(self,request,view)
返回True放行;返回False直接抛403无权限。

  1. 频率类 Throttle

接口访问限流,防刷接口。
继承SimpleRateThrottle

  • rate = "5/d" 每天最多5次
  • 重写get_cache_key(self,request,view) 返回限流的key(按用户id / ip限流)

2.7 排序、过滤、分页、全局异常

  1. 排序:OrderingFilter,?ordering=-price负号代表降序
  2. 搜索过滤:SearchFilter,?search=关键词
  3. 精确过滤:DjangoFilterBackend,?name=xxx
  4. 自定义过滤:继承BaseFilterBackend,重写filter_queryset,返回过滤后的queryset
  5. 分页:DRF提供3套分页类,配置pagination_class
  6. 全局异常处理
    DRF自带异常处理器返回格式不统一,需要自己写异常函数:
  • 参数固定exc,context
  • 返回必须是Response对象,统一格式{code:xxx,msg:"xxx"}
  • 用isinstance区分不同异常类型,区分错误码
  • 可以记录日志,从context拿到request、view对象

2.8 接口文档

  • 文档载体:md、第三方在线平台、drf‑spectacular自动生成文档。
  • 自动生成文档:drf‑spectacular

2.9 JWT回顾

  1. JWT原理:三段式 header.payload.signature,base64编码 + 哈希签名
  2. 手写JWT:登录签发、认证解析校验签名和过期时间
  3. simple‑jwt第三方库使用:双token access/refresh

三、源码重点阅读

3.1 Serializer中 many=True 源码逻辑

  1. 实例化序列化对象,先走魔术方法 __new__(创建对象)
  2. 如果传入many=True,不会直接创建本类对象,调用many_init()
  3. many_init内部创建 ListSerializer,把当前序列化类作为child传入
  4. 最终得到的是ListSerializer实例,内部包含多条子序列化对象

many=True:对象是ListSerializer;many=False才是你写的序列化类本身。

3.2 is_valid() 校验执行流程

调用 serializer.is_valid() → 执行run_validation()

run_validation()
└── to_internal_value()   # ①执行局部钩子 validate_xxx字段
    └── run_validators() # 字段内置校验
    └── validate()       # ②执行全局钩子 validate(self,attrs)
  • 局部钩子:to_internal_value内部通过反射getattr找validate_字段名
  • 全局钩子:validate(self,attrs),必须把校验完的attrs返回出去。

面试简答速记

  1. APIView三大认证顺序:认证类 → 权限类 → 频率类
  2. many=True本质:外层套ListSerializer
  3. 序列化校验顺序:字段自身校验 → 局部钩子 → 全局钩子
  4. 权限模型
    • ACL:用户直接绑定权限
    • RBAC:用户‑角色‑权限(企业后台最常用)
  5. DRF全局异常处理器要求:函数参数exc,context,返回Response对象。

如果你需要,我可以把这份笔记再压缩成考试背诵极简版。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容