视图家族

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. oracle函数 DUMP(w[,x[,y[,z]]])

    [功能]返回数据类型.字节长度和在内部的存储位置. [参数] w为各种类型的字符串(如字符型.数值型.日期型……) x为返回位置用什么方式表达,可为:8,10,16或17,分别表示:8/10/16进制 ...

  2. Shell 基本运算符 1

    Shell 和其他编程语言一样,支持多种运算符,包括: 算术运算符 关系运算符 字符串运算符 文件测试运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr ...

  3. css3 word-wrap属性

    允许长单词换行到下一行: word-wrap:break-word

  4. winform(C#)里弹出“确定”“取消”对话框

    //消息框中需要显示哪些按钮,此处显示“确定”和“取消” MessageBoxButtons messButton = MessageBoxButtons.OKCancel; //"确定要退 ...

  5. MySQL数据库字符集和整理

    MySQL数据库字符集和整理(2009-11-20 22:23:37) mysql数据库 it    其实这个表在MySQL数据库中通过phpMyAdmin就能看到,icech只是把表格整理了一下方便 ...

  6. C++调用Lua编程环境搭建及测试代码示例

    C++调用Lua编程环境搭建及测试代码示例 摘要:测试环境是VS2005+LuaForWindows_v5.1.4-45.exe+WIN7 1.安装lua开发环境LuaForWindows_v5.1. ...

  7. 微信小程序wx.request 请求方法

    data: 最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String .转换规则如下: 对于 GET 方法的数据,会将数据转换成 quer ...

  8. uni-app 生命周期函数

    应用生命周期 函数名 说明 onLaunch 当uni-app 初始化完成时触发(全局只触发一次) onShow 当 uni-app 启动,或从后台进入前台显示 onHide 当 uni-app 从前 ...

  9. linux版本依赖

    记住, 你的模块代码一定要为每个它要连接的内核版本重新编译 -- 至少, 在缺乏 modversions 时, 这里不涉及因为它们更多的是给内核发布制作者, 而不是开发者. 模块 是紧密结合到一个特殊 ...

  10. java 内省 了解JavaBean

    JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则. 如果要在两个模块之间传递多个信息,可以将这些信息封装到一个Jav ...