DRF 06
视图家族
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的更多相关文章
- 06 drf源码剖析之权限
06 drf源码剖析之权限 目录 06 drf源码剖析之权限 1. 权限简述 2. 权限使用 3.源码剖析 4. 总结 1. 权限简述 权限与身份验证和限制一起,决定了是否应授予请求访问权限. 权限检 ...
- 06.drf(django)的权限
默认配置已经启用权限控制 settings 'django.contrib.auth', 默认 migrate 会给每个模型赋予4个权限,如果 ORM 类不托管给django管理,而是直接在数据库中建 ...
- python 全栈开发,Day104(DRF用户认证,结算中心,django-redis)
考试第二部分:MySQL数据库 6. MySQL中char和varchar的区别(1分) char是定长,varchar是变长. char的查询速度比varchar要快. 7. MySQL中va ...
- python 全栈开发,Day99(作业讲解,DRF版本,DRF分页,DRF序列化进阶)
昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...
- python 全栈开发,Day97(Token 认证的来龙去脉,DRF认证,DRF权限,DRF节流)
昨日内容回顾 1. 五个葫芦娃和三行代码 APIView(views.View) 1. 封装了Django的request - request.query_params --> 取URL中的参数 ...
- (四) DRF认证, 权限, 节流
一.Token 认证的来龙去脉 摘要 Token 是在服务端产生的.如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端.前端可以在每次请求的时候带上 To ...
- VUE+DRF系列
vue基础系列 001 路飞学诚项目简介 002 Vue简介 003 Vue引入 004 文本指令 005 事件指令 006 斗篷指令 007 属性指令 008 表单指令 009 条件指令 010 路 ...
- 二.drf之使用序列化编写视图
总结:两功能序列化: a.拿到queryset --->idc = Idc.objects.all() b.将queryset给序列化成类---->serializer = IdcSeri ...
- drf源码剖析系列(系列目录)
drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...
随机推荐
- oracle函数 DUMP(w[,x[,y[,z]]])
[功能]返回数据类型.字节长度和在内部的存储位置. [参数] w为各种类型的字符串(如字符型.数值型.日期型……) x为返回位置用什么方式表达,可为:8,10,16或17,分别表示:8/10/16进制 ...
- Shell 基本运算符 1
Shell 和其他编程语言一样,支持多种运算符,包括: 算术运算符 关系运算符 字符串运算符 文件测试运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr ...
- css3 word-wrap属性
允许长单词换行到下一行: word-wrap:break-word
- winform(C#)里弹出“确定”“取消”对话框
//消息框中需要显示哪些按钮,此处显示“确定”和“取消” MessageBoxButtons messButton = MessageBoxButtons.OKCancel; //"确定要退 ...
- MySQL数据库字符集和整理
MySQL数据库字符集和整理(2009-11-20 22:23:37) mysql数据库 it 其实这个表在MySQL数据库中通过phpMyAdmin就能看到,icech只是把表格整理了一下方便 ...
- C++调用Lua编程环境搭建及测试代码示例
C++调用Lua编程环境搭建及测试代码示例 摘要:测试环境是VS2005+LuaForWindows_v5.1.4-45.exe+WIN7 1.安装lua开发环境LuaForWindows_v5.1. ...
- 微信小程序wx.request 请求方法
data: 最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String .转换规则如下: 对于 GET 方法的数据,会将数据转换成 quer ...
- uni-app 生命周期函数
应用生命周期 函数名 说明 onLaunch 当uni-app 初始化完成时触发(全局只触发一次) onShow 当 uni-app 启动,或从后台进入前台显示 onHide 当 uni-app 从前 ...
- linux版本依赖
记住, 你的模块代码一定要为每个它要连接的内核版本重新编译 -- 至少, 在缺乏 modversions 时, 这里不涉及因为它们更多的是给内核发布制作者, 而不是开发者. 模块 是紧密结合到一个特殊 ...
- java 内省 了解JavaBean
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则. 如果要在两个模块之间传递多个信息,可以将这些信息封装到一个Jav ...