视图家族

views视图类

  • APIView
"""
1.继承View类
2.重写了as_view方法: 局部禁用csrf
3.重写了dispatch方法: 请求, 响应, 解析, 渲染, 异常, 三大认证
4.一系列类属性: 局部和全局配置
作用: drf最底层视图, 所有视图直接或者间接继承了APIView, 理论上可以完成所有接口需求
"""
  • GenericAPIView
"""
1.继承了APiView
2.get_queryset方法, 需要在视图类中配置queryset类属性
3.get_object方法, 可以在视图类中配置lookup_url_kwarg和lookup_field类属性, 默认是按pk
4.get_serializer方法, 需要在视图类中配置serializer_class类属性 总结:GenericAPIView就是在APIView基础上额外提供了三个方法,三个类属性,如果不配合视图工具类,体现不出优势
目的:视图中的增删改查逻辑相似,但操作的资源不一致,操作资源就是操作 资源对象们(queryset)、资源对象(object)以及资源相关的序列化类(serializer),将这三者形成配置,那操作逻辑就一致,就可以进行封装
""" class GenericAPIView(views.APIView):
# 需要自己配置的几个属性
queryset = None
serializer_class = None
lookup_field = 'pk'
lookup_url_kwarg = None def get_queryset(self):
# queryset为None就抛异常, 因此我们要在视图类中自定义queryset属性
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
) ... return queryset def get_object(self):
queryset = self.filter_queryset(self.get_queryset()) # 如果设置了就按lookup_url_kwarg, 没有设置就按lookup_field, 也就是"pk"
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
assert lookup_url_kwarg in self.kwargs, (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwarg)
) ... return obj def get_serializer(self, *args, **kwargs):
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs) def get_serializer_class(self):
# serializer_class为None就抛异常, 因此我们要在视图类中自定义serializer_class属性
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
) return self.serializer_class
from rest_framework.generics import GenericAPIView
# 利用GenericAPIView实现单查群查
class CarGenericAPIView(GenericAPIView):
# 配置queryset
queryset = models.Car.objects.filter(is_delete=False).all()
# 配置序列化类
serializer_class = CarModelSerializer # url有名分组的传递关键字参数的key: car_pk = kwargs.get('pk')
lookup_url_kwarg = 'pk'
# 进数据库查询的筛选字段: models.Car.objects.filter(pk=car_pk).first
lookup_field = 'pk' # 群查
def get(self, request, *args, **kwargs):
car_query = self.get_queryset()
serializer_obj = self.get_serializer(instance=car_query, many=True)
return APIResponse(results=serializer_obj.data) # 单查
def get(self, request, *args, **kwargs):
car_obj = self.get_object()
serializer_obj = self.get_serializer(instance=car_obj)
return APIResponse(results=serializer_obj.data)

mixin视图工具类

  • 视图工具类都是基于GenericAPIView来使用的, 因此我们的视图类都要先继承GenericAPIVIew
  • 五个工具类, 六个方法
"""
1.RetrieveModelMixin
retrieve方法: 单查 2.ListModelMixin
list方法: 群查 3.CreateModelMixin
create方法: 单增 4.UpdateModelMixin
update方法: 整体单改
partial_update方法: 局部单改 5.DestroyModelMixin
destory方法: 单删
""" from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, \
UpdateModelMixin # mixin视图工具类
class CarReadModelGenericAPIView(ListModelMixin, RetrieveModelMixin, CreateModelMixin, GenericAPIView):
queryset = models.Car.objects.filter(is_delete=False).all()
serializer_class = CarModelSerializer
lookup_url_kwarg = 'pk' # 群查: ListModelMixin下面的list方法
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) # 单查: RetrieveModelMixin下面的retrieve方法
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs) # 单增: CreateModelMixin下面的create方法
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)

generics工具视图类

  • 九种组合
"""
1.都继承了GenericAPIView
2.继承了不同组合的Mixin
3.不同的组合实现了get, post, put, patch, delete方法
4.我们自需要配置queryset, serializer_class, lookup_url_kwarg, lookup_field几个类属性即可
""" from rest_framework.generics import RetrieveAPIView, ListAPIView, RetrieveUpdateDestroyAPIView # 单查: RetrieveAPIView下面的get方法
class CarRetrieveAPIView(RetrieveAPIView):
queryset = models.Car.objects.filter(is_delete=False).all()
serializer_class = CarModelSerializer
lookup_url_kwarg = 'pk' # 群查: ListAPIView下面的get方法
class CarListAPIView(ListAPIView):
queryset = models.Car.objects.filter(is_delete=False).all()
serializer_class = CarModelSerializer # 单查, 整体单改, 局部单改, 单删
class CarRetrieveUpdateDestroyAPIView(RetrieveUpdateDestroyAPIView):
queryset = models.Car.objects.filter(is_delete=False).all()
serializer_class = CarModelSerializer

viewsets视图集

  • ViewSetMixin
"""
视图集都继承ViewSetMixin, 该类重写as_view方法, 相比于APIView的as_view方法(局部禁用csrf), 多了一个参数: actions, as_view(actions={'get': 'list'}), 通过__getattr__和__setattr__给视图类增加了get属性, 该属性指向list方法, 因此向该url提交get请求, 就会触发视图类下面的list方法
ViewSetMixin只提供as_view方法, 没有写dispatch方法, 也没有继承任何类, 因此我们是不能直接拿来用的 """
class ViewSetMixin:
def as_view(cls, actions=None, **initkwargs): ... # actions: {'get': 'list'}
for method, action in actions.items():
# 通过反射获取视图类下面的list方法
handler = getattr(self, action)
# 将list方法赋值给get属性
setattr(self, method, handler) ... return csrf_exempt(view)
  • GenericViewSet和ViewSet两个视图集基类
"""
这两货啥都没写, 就是多继承了一个类, 用来提供dispatch方法
""" # 该分支满足的接口与资源Model类关系不是特别密切:登录接口、短信验证码接口
class ViewSet(ViewSetMixin, views.APIView):
pass # 该分支严格满足资源接口
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
pass
  • ReadOnlyModelViewSet和ModelViewSet两个视图集子类
"""
这两货好像也是啥都没干, 就行进行了Mixin视图工具类和GenericAPIView的组装
""" class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass

路由配置

urlpatterns = [
url(r'^v4/car/$', views.CarGenericViewSet.as_view({
'get': 'list',
'post': 'create',
'put': 'many_update',
'patch': 'many_partial_update',
'delete': 'many_destroy'
})), url(r'^v4/car/(?P<pk>\d+)/$', views.CarGenericViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
})) ]
# DRF的路由组件
from rest_framework.routers import SimpleRouter # 生成SimpleRouter对象
router = SimpleRouter()
# 参数: 路由, 视图类, 资源名称
router.register('v4/car', views.CarModelViewSet, basename='car') urlpatterns = [
url(r'', include(router.urls))
]

DRF 06的更多相关文章

  1. 06 drf源码剖析之权限

    06 drf源码剖析之权限 目录 06 drf源码剖析之权限 1. 权限简述 2. 权限使用 3.源码剖析 4. 总结 1. 权限简述 权限与身份验证和限制一起,决定了是否应授予请求访问权限. 权限检 ...

  2. 06.drf(django)的权限

    默认配置已经启用权限控制 settings 'django.contrib.auth', 默认 migrate 会给每个模型赋予4个权限,如果 ORM 类不托管给django管理,而是直接在数据库中建 ...

  3. python 全栈开发,Day104(DRF用户认证,结算中心,django-redis)

    考试第二部分:MySQL数据库 6.  MySQL中char和varchar的区别(1分) char是定长,varchar是变长. char的查询速度比varchar要快. 7.   MySQL中va ...

  4. python 全栈开发,Day99(作业讲解,DRF版本,DRF分页,DRF序列化进阶)

    昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...

  5. python 全栈开发,Day97(Token 认证的来龙去脉,DRF认证,DRF权限,DRF节流)

    昨日内容回顾 1. 五个葫芦娃和三行代码 APIView(views.View) 1. 封装了Django的request - request.query_params --> 取URL中的参数 ...

  6. (四) DRF认证, 权限, 节流

    一.Token 认证的来龙去脉 摘要 Token 是在服务端产生的.如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端.前端可以在每次请求的时候带上 To ...

  7. VUE+DRF系列

    vue基础系列 001 路飞学诚项目简介 002 Vue简介 003 Vue引入 004 文本指令 005 事件指令 006 斗篷指令 007 属性指令 008 表单指令 009 条件指令 010 路 ...

  8. 二.drf之使用序列化编写视图

    总结:两功能序列化: a.拿到queryset --->idc = Idc.objects.all() b.将queryset给序列化成类---->serializer = IdcSeri ...

  9. drf源码剖析系列(系列目录)

    drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...

随机推荐

  1. dataframe构建

    data=[[[0],1]]df = pd.DataFrame(data, columns=['col1', 'col2']) df = pd.DataFrame({‘col1’:‘’,‘col2’: ...

  2. @codeforces - 1187F@ Expected Square Beauty

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个序列 x = {x1, x2, ..., xn},已知 ...

  3. [ZJOI2007] 小Q的矩阵游戏 (模板—Dinic)

    B. 矩阵游戏 题目描述 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行 ...

  4. ORACLE 创建pfile和spfile

        使用服务器参数文件spfile创建文本参数文件pfile:1,SQL> create pfile from spfile="/u01/app/oracle/product/9. ...

  5. Android本地数据存储: ASimpleCache

    一:前言 在上一篇博客Android本地数据存储: Reservoir 博客中,我提到,除了Reservoir库,还可以采用ASimpleCache开源库,来实现本地数据存储.昨天并没有仔细的对比Re ...

  6. TCP/IP模型的层次结构

  7. php中 instanceof有什么作用

    php中 instanceof有什么作用 作用:(1)判断一个对象是否是某个类的实例,(2)判断一个对象是否实现了某个接口.

  8. Python--day29--configparser模块(配置)(不熟,以后要找时间重学)

  9. Python--day24--多继承

    如果本生没有func方法的话就调用距离自己最近的基类的方法 钻石继承: 查找方法的顺序:如下例的找func方法(广度优先) 例1: 例2: 漏斗继承: 小乌龟继承问题:(最顶端的节点F是最后查找的) ...

  10. H3C PPP的特点