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 ...
随机推荐
- LightOJ 1370 Bi-shoe and Phi-shoe【欧拉函数 && 质数】
题目链接: http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1370 题意: 给定值,求满足欧拉值大于等于这个 ...
- 【BZOJ1227】[SDOI2009]虔诚的墓主人
E. 虔诚的墓主人 题目描述 小W 是一片新造公墓的管理人.公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.当地的居民都是非常虔诚的基督徒,他们愿意提前 ...
- html实体字符转换成字符串
function EntityToString(value) { let tag = document.createElement("div"); tag.innerHTML = ...
- 源映射错误:request failed with status 404
源映射错误:request failed with status 404:源映射错误:request failed with status 404
- Windows Community Toolkit 3.0 新功能 在WinForms 和 WPF 使用 UWP 控件
本文告诉大家一个令人震惊的消息,Windows Community Toolkit 有一个大更新,现在的版本是 3.0 .最大的提升就是 WinForm 和 WPF 程序可以使用部分 UWP 控件. ...
- H3C 帧中继虚电路
- tp5 select出来数据集(对象)转成数组
1.先在数据库配置文件中 //数据集返回类型 'resultset_type' => 'collection', 2.在使用时, 使用 toArray() 方法 //查询数据库 $news = ...
- Vue进阶
组件深入 过渡&动画 可复用性&组合 工具&规模化&内在 ****************参考*************** vue官方教程
- springboot + redis + 注解 + 拦截器 实现接口幂等性校验
一.概念 幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次 比如: 订单接口, 不能多次创建订单 支付接口, 重复支付同一笔订单只能扣一次钱 支付宝回调接口, 可能会多 ...
- Python--day40--datetime,socketserver,Threading模块分别是哪些模块的高层模块