视图家族

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. Jmeter非命令行执行脚本

    这次我们可以清晰地看到每个线程的执行情况.        这里是我们使用非 GUI 模式运行测试脚本时可以使用的一些命令: -h 帮助 -> 打印出有用的信息并退出 -n 非 GUI 模式 -& ...

  2. @codeforces - 1214F@ Employment

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有 m 个城市围成一个圆环,编号为 1~m. 某公司有 n 个职 ...

  3. 如何用Chrome浏览器下载网页音乐视频

    打开网页,先让要下载的视频播放,右键单击选择审查元素(F12),选择上方的Network选项,按F5刷新,这个时候我们可以看到框架中Size下的不少文件数据数字正在变大,按size降序排列.点击表格的 ...

  4. OpenStack☞HTTP协议

    前言 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准 HTTP是一个基于TCP/IP通信协议 ...

  5. python selenium处理JS只读(12306)

    12306为例 js = "document.getElementById('train_date').removeAttribute('readonly');" driver.e ...

  6. uva 10566 Crossed Ladders (二分)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  7. H3C 使用命令视图

  8. 20190528-JavaScriptの打怪升级旅行 { 语句 [ 赋值 ,数据 ] }

    写在前面的乱七八糟:今天考了试,emmm很基础的题,还是Mrs房的面试题让人绝望啊┓( ´∀` )┏,补了很多知识,很综合的题,坑也很多,总的来说,查漏补缺,其实是啥都缺~ 今天打的小BOSS主要是数 ...

  9. TAE words all

    // vol 1   could do with sth   rhinoplasty   angst   the wee small hours   familial   Munich   gladi ...

  10. Mac MAMP 使用终端shell操作mysql数据库

    在MAMP中已经集成了phpMyAdmin,可以很方便的管理mysql数据库,但是有的情况是phpMyAdmin不能做到的.比如,导入sql文件,当sql文件非常大(大于20MB)的时候,apache ...