- Title(EN): Django REST Framework Learning Notes (10): Generic Views, MixIns, ViewSets and Routers
- Author: dog2
基本信息
- 源码
- rest_framework.views
- rest_framework.generics
- rest_framework.viewsets
- rest_framework.routers
- 官方文档
- API Guide - Generic views
- API Guide - ViewSets
- API Guide - Routers
- 本文demo代码Github
AIPView - API视图类
APIView
是Django REST Framework提供的所有视图的基类,继承自Django的View
父类。
与Django View
的不同
- 传入到视图方法中的是REST framework的
Request
对象,而不是Django的HttpRequeset
对象 - 视图方法可以返回REST framework的
Response
对象,视图会为响应数据设置(render)符合前端要求的格式 - 任何
APIException
异常都会被捕获到,并且处理成合适的响应信息 - 在进行
dispatch()
分发前,会对请求进行身份认证、权限检查、流量控制
重要类属性
AIPView
有如下可设置的重要类属性:
authentication_classes
:列表或元祖,身份认证类permissoin_classes
:列表或元祖,权限检查类throttle_classes
:列表或元祖,流量控制类
示例代码
在APIView
中仍有get()
,post()
等其他请求方式的方法
1 | from rest_framework.views import APIView |
GenericAPIView - 通用API视图类
通用API视图类GenericAPIView
继承自APIView
,完全兼容APIView
,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin
扩展类的执行提供基础类支持。通常在使用时,可以配合一个或多个Mixin
扩展类。
GenericAPIView
比APIView
多了什么
get_queryset()
:从类属性queryset中
获得model
的queryset
数据。群操作就走get_queryset()
方法(包括群查,群增等)。get_object()
:从类属性queryset
中获得model
的queryset
数据,再通过有名分组pk
确定唯一操作对象。单操作就走get_object()
方法(包括单查,单增等)。get_serializer()
:从类属性serializer_class
中获得serializer
的序列化类。
重要类属性
GenericAPIView
有如下可设置的重要类属性:
- 列表视图与详情视图共用
queryset
:指明视图需要的数据(model
查询数据)permissoin_classes
:指明视图使用的序列化器
- 列表视图使用
pagination_class
:指定分页控制类filter_backends
:指定过滤控制后端
- 详情页视图使用
lookup_field
:自定义主键,有名分组的查询,默认是pk
lookup_url_kwarg
:查询单一数据时url中的参数关键字名称,默认与look_field
相同
重要类方法
get_queryset()
:从类属性queryset
中获得model
的queryset
数据get_object()
:从类属性queryset
中获得model
的queryset
数据,再通过有名分组pk
来确定唯一操作对象get_serializer()
:从类属性serializer_class
中获得serializer
的序列化类,主要用来提供给Mixin
扩展类使用
get_serializer
源码
1 | def get_serializer(self, *args, **kwargs): |
示例代码
视图层 views.py
1 | class BookGenericAPIView(GenericAPIView): |
路由层 urls.py
1 | urlpatterns = [ |
xxxModelMixin
- 视图类的模型工具集
作用
- 提供了几种后端视图(对数据资源的增删改查)处理流程的实现,如果需要编写的视图属于这五种,则视图可以通过继承相应的扩展类来复用代码,减少自己编写的代码量。
mixins
有五个工具类文件,一共提供了五个工具类,六个工具方法:单查、群查、单增、单删、单整体改、单局部改
使用
- 继承工具类可以简化请求函数的实现体,但是必须继承
GenericAPIView
,需要GenericAPIView
类提供序列化器与数据库查询的方法(见上方GenericAPIView
基类知识点) - 工具类的工具方法返回值都是
Response
类型对象,如果要格式化数据格式再返回给前台,可以通过response.data
拿到工具方法返回的Response
类型对象的响应数据
五大模型工具类
ListModelMixin
群查
- 列表视图扩展类,提供
list
方法快速实现查询视图 - 返回
200
状态码 - 除了查询,该
list
方法会对数据进行过滤和分页
CreateModelMixin
单增
- 创建视图扩展类,提供
create
方法快速创建资源的视图,成功返回201
的状态码 - 没有群增的方法,需要自己手动写
RetrieveModelMixin
单查
- 详情视图扩展类,提供
retrieve
方法,可以快速实现返回一个存在的数据对象
UpdateModelMixin
更新/修改
- 更新视图扩展类,提供
update
方法,可以快速实现更新一个存在的数据对象,同时也提供partial_update
方法,可以实现局部更新 - 只有单整体改和单局部改,没有群整体改和群局部改
DestoryModelMixin
删除
- 删除视图扩展类,提供
destory
方法,可以快速实现删除一个存在数据对象 - 一般不怎么用到,因为实际开发中并不会真的删除数据,而是修改是否可用的标记
示例代码
视图层 views.py
1 | from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin |
路由层 urls.py
1 | urlpatterns = [ |
xxxAPIView - 功能性子视图类
功能性子视图类继承了GenericAPIView
和各种Mixins
工具类
- 功能性视图类都是
GenericAPIView
的子类,且不同的子类继承了不同的工具类 - 工功能性视图类的功能可以满足需求,只需要继承工具视图,并且提供
queryset
与serializer_class
即可
各大功能子视图类
一表胜千言:
视图 | 作用 | 请求类型 | 父类 |
---|---|---|---|
ListAPIView | 查询多条数据 | get | GenericAPIView ListModelMixin |
CreateAPIView | 新增一条数据 | post | GenericAPIView CreateModelMixin |
RetrieveAPIView | 查询一条数据 | get | GenericAPIView RetrieveModelMixin |
UpdateAPIView | 修改一条数据 | put patch |
GenericAPIView UpdateModelMixin |
DestroyAPIView | 删除一条数据 | delete | GenericAPIView DestroyModelMixin |
RetrieveUpdateAPIView | 单查 更新一条数据 |
get put patch |
GenericAPIView RetrieveModelMixin UpdateModelMixin |
RetrieveUpdateDestroyAPIView | 单查 更新 删除一条数据 |
get put patch delete |
GenericAPIView RetrieveModelMixin UpdateModelMixin DestroyModelMixin |
ListCreateAPIView | 群查 更新一条 |
get post |
GenericAPIView ListModelMixin mixins.CreateModelMixin |
示例代码
视图层 views.py
1 | from rest_framework.generics import ListCreateAPIView, UpdateAPIView |
路由层 urls.py
1 | urlpatterns = [ |
xxxViewset - 视图集
常用视图集父类
ViewSetMixin
ViewSetMixin
主要是自定义了as_view
方法,使可以通过其参数指定 HTTP_METHOD
与函数的映射关系,如 view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
ViewSet
继承自APIView
和ViewSetMixin
,没有提供任何方法,需要自己写
GenericViewSet
继承GenericAPIView
和ViewSetMixin
,其中GenericAPIView
提供了基础方法,可以直接搭配Mixin
扩展类使用,因此比较常用
ModelViewSet
继承GenericViewset
,但同时也包括ListModelMixin
、CreateModelMixin
等mixin
扩展类
源码分析
- 视图集都是默认优先继承
ViewSetMixin
类,再继承一个视图类(GenericAPIView
或APIView
) ViewSetMixin
提供了重写的as_view()
方法,继承视图集的视图类,配置路由时调用as_view()
必须传入 请求名-函数名 映射关系字典
例如:
1 | path('v5/books/', views.BookGenericViewSet.as_view({'get': 'my_get_list'})), |
表示get
请求会交给my_get_list
视图函数处理
GenericViewSet 示例代码
路由层 urls.py
1 | urlpatterns = [ |
视图层 views.py
1 | from rest_framework.viewsets import GenericViewSet |
GenericViewSet
与ViewSet
异同
GenericViewSet
和ViewSet
都继承了ViewSetMixin
,as_view
都可以配置 请求-函数 映射GenericViewSet
继承的是GenericAPIView
视图类,用来完成标准的model
类操作接口ViewSet
继承的是APIView
视图类,用来完成不需要model
类参与,或是非标准的model
类操作接口,如post
请求在标准的model
类操作下就是新增接口,登陆的post
不满足。登陆的post请求,并不是完成数据的新增,只是用post提交数据,得到的结果也不是登陆的用户信息,而是登陆的认证信息post
请求验证码的接口,不需要model
类的参与
源码
- GenericViewSet
1 | # viewsets.py |
- ViewSet
1 |
|
ModelViewSet 示例代码
路由层 urls.py
1 | urlpatterns = [ |
视图层 views.py
1 | class BookModelViewSet(ModelViewSet): |
路由组件
因为具有局限性,所以在开发复杂接口时并不是首选。
示例代码如下:
1 | from django.urls import path, include |
总结
一图胜千言,非原创,均来自网络: