rest framework 视图,路由
视图
在上面序列化的组件种已经用到了视图组件,即在视图函数部分进行逻辑操作。
但是很明显的弊端是,对每个表的增删改查加上 单条数据,需要用到 2个类 5个方法(增删改查,单数据查)才可以完整的实现,当表的数量较大的时候,就很蠢了。
因此 rest framework 也对这个进行了多层的封装。
源码位置
rest_framework.viewsets
rest_framework.generics
rest_framework.mixins
最底层的三个基础文件
rest_framework.viewsets
# 内部提供了 as_view 方法
class ViewSetMixin(object):
# 此方法提供了 as_view 方法可以加参数的条件
def as_view(cls, actions=None, **initkwargs):... # 用作总的继承类
class GenericViewSet(ViewSetMixin, generics.GenericAPIView): ... # 单数据分支继承类 ,只有全数据和单数据的查看方法
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):... # 全数据分支继承类,最全内置增删改查 以及 单数据查看方法 5个全都有
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):...
rest_framework.generics
class GenericAPIView(views.APIView):
# queryset 数据对象传入用变量
queryset = None
# 在视图中序列化工具对象传入用变量
serializer_class = None # 以下是一些增删改查的各种共功能组合 ,用于继承类使用 class CreateAPIView(mixins.CreateModelMixin,
GenericAPIView): class ListAPIView(mixins.ListModelMixin,
GenericAPIView): class RetrieveAPIView(mixins.RetrieveModelMixin,
GenericAPIView): class DestroyAPIView(mixins.DestroyModelMixin,
GenericAPIView): class UpdateAPIView(mixins.UpdateModelMixin,
GenericAPIView): class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView): class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
GenericAPIView): class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
GenericAPIView): class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
rest_framework.mixins
内置的操作方法 增删改查 单行数据查询都在这里
class CreateModelMixin(object): ... class ListModelMixin(object): ... class RetrieveModelMixin(object): ... class UpdateModelMixin(object): ... class DestroyModelMixin(object): ...
彼此继承关系图
基于底层三类进行了两轮封装
GenrericViewSet 封装了 GenericAPIView 和 ViewSetMixin ,于是获得了 传入对象以及 重写 as_view 的功能
ModelViewSet 封装了 GenrericViewSet 和 mixins ,在 GenrericViewSet 的基础上 又获得了 增删改查方法的集成
最初始最全面也是最笨的方式操作表
方式1 2类5方法无判断
对于全部数据的查询以及数据的创建不需要带参数,设计为一条URL
其他单数据的查看编辑和删除在设计一条URL
两条URL 分别对应两个类
全部的内容:
写全了就是 2个类 ,加起来一共5方法
各类中的请求对应方式
class BookView(APIView):
def get(self,request): # 对所有数据进行查看
book_list=Book.objects.all()
bs=BookModelSerializers(book_list,many=True,context={'request': request})
return Response(bs.data)
def post(self,request): # 对数据进行创建提交
# post请求的数据
bs=BookModelSerializers(data=request.data)
if bs.is_valid():
print(bs.validated_data)
bs.save() # .create()方法
return Response(bs.data)
else:
return Response(bs.errors) class BookDetailView(APIView): def get(self,request,id): # 对单条数据进行查看 book=Book.objects.filter(pk=id).first()
bs=BookModelSerializers(book,context={'request': request})
return Response(bs.data) def put(self,request,id): # 对单条数据进行更新
book=Book.objects.filter(pk=id).first()
bs=BookModelSerializers(book,data=request.data)
if bs.is_valid():
bs.save() # .updata()
return Response(bs.data)
else:
return Response(bs.errors) def delete(self,request,id): # 删除数据
Book.objects.filter(pk=id).delete()
return Response()
方式2 一类5方法带判断
只写一个类,内含5方法,在get 的时候进行一次判断即可
class IndexView(views.APIView): def get(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if pk:
pass # 获取单条信息
else:
pass # 获取列表信息 def post(self,request,*args,**kwargs):
pass def put(self,request,*args,**kwargs):
pass def patch(self,request,*args,**kwargs):
pass def delete(self,request,*args,**kwargs):
pass
class SchoolView(APIView):
def get(self, request, *args, **kwargs):
query_set = models.School.objects.all()
ser_obj = app01_serializers.SchoolSerializer(query_set, many=True)
return Response(ser_obj.data) class SchoolDetail(APIView):
def get(self, request, pk, *args, **kwargs):
obj = models.School.objects.filter(pk=pk).first()
ser_obj = app01_serializers.SchoolSerializer(obj)
return Response(ser_obj.data)
第一次整合
利用GenericeAPIView 传入 queryset对象以及 序列化对象, 再利用内置的 mixins 中的操作方法省去操作代码
from rest_framework.generics import GenericAPIView
from rest_framework import.mixins class SchoolView(GenericAPIView, mixins.ListModelMixin):
queryset = models.School.objects.all()
serializer_class = app01_serializers.SchoolSerializer def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) class SchoolDetail(GenericAPIView, mixins.RetrieveModelMixin, mixins.CreateModelMixin):
queryset = models.School.objects.all()
serializer_class = app01_serializers.SchoolSerializer def get(self, request, pk, *args, **kwargs):
return self.retrieve(request, pk, *args, **kwargs) def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
路由依旧是分成两条,单数据和多数据分开
url(r'school/$', views.SchoolView.as_view()),
url(r'school/(?P<pk>\d+)/$', views.SchoolDetail.as_view()),
第二次整合
利用GenericeAPIView 传入 queryset对象以及 序列化对象, 再利用内置的 generics 中的操作方法省去操作代码
from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView
class SchoolView(ListCreateAPIView):
queryset = models.School.objects.all()
serializer_class = app01_serializers.SchoolSerializer class SchoolDetail(RetrieveUpdateDestroyAPIView):
queryset = models.School.objects.all()
serializer_class = app01_serializers.SchoolSerializer
路由依旧是分成两条,单数据和多数据分开,同第一次整合无区别
url(r'school/$', views.SchoolView.as_view()),
url(r'school/(?P<pk>\d+)/$', views.SchoolDetail.as_view()),
终极版
直接继承最终的 ModelViewSet 继承类 ,ModelViewSet 在 ViewSetMixin 类 之上,可以重写 as_view 方法能够添加参数
from rest_framework.viewset import ModelViewSet
class SchoolView(ModelViewSet):
queryset = models.School.objects.all()
serializer_class = app01_serializers.SchoolSerializer
因为视图被极大的压缩,参数的传递交给了 as_view 来处理,因此 url 会变得比以往复杂,url 还可以进一步封装,详情往下看路由部分
url(r'school/$', views.SchoolView.as_view({
"get": "list",
"post": "create",
})),
url(r'school/(?P<pk>\d+)/$', views.SchoolView.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
})),
终极版自定制
class P2(PageNumberPagination):
page_size = 3 #每一页显示的条数
page_query_param = 'page' #获取参数中传入的页码
page_size_query_param = 'size' #获取url参数中每页显示的数据条数 max_page_size = 5 class IndexSerializer(ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__" class IndexView4(ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = IndexSerializer
pagination_class = P2 def list(self, request, *args, **kwargs):
'''获取get请求的所有'''
pass def retrieve(self, request, *args, **kwargs):
'''查看单条数据'''
pass
def destroy(self, request, *args, **kwargs):
'''删除DELETE'''
pass
def create(self, request, *args, **kwargs):
'''添加数据POST'''
pass
def update(self, request, *args, **kwargs):
'''全部修改PUT'''
pass
def partial_update(self, request, *args, **kwargs):
'''局部修改PATCH'''
pass
二次整理版本( 浓缩版 )
"""
继承结构 (功能↓) (封装↑)
ModelViewSet/ReadOnlyModelViewSet
generics.xxx GenericViewSet
mixins.xxx GenericAPIView
APIView
ViewSetMixin 基础的四个功能组件(每个都有自己独有功能)
APIView(View)
啥都没有, 全部手写去吧 ViewSetMixin(object)
提供了 as_view 的重写
以及 initialize_request 里面很多的 action mixins.xxx(object)
提供以下的 5 个基础的增删改查方法,
CreateModelMixin - create() post()
ListModelMixin - list() get()
RetrieveModelMixin - retrieve() patch()
DestroyModelMixin - destroy() delete()
UpdateModelMixin - update() put() GenericAPIView(views.APIView)
提供了以下字段的封装, 不需要手写了
queryset = None 数据库对象
serializer_class = None 序列化对象
lookup_field = 'pk' 默认查询字段, 默认是 id
lookup_url_kwarg = None 查询单一数据时URL中的参数关键字名称, 默认与look_field相同
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS 过滤
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS 分页器选择 进阶的两个(对基础组件的一层封装)
GenericViewSet(ViewSetMixin, generics.GenericAPIView)
集合了 as_view 以及 可写参数 generics.xxxx.....(mixins.xxxxx,GenericAPIView)
各式的组合增删改查, 以及附加参数功能
CreateAPIView(mixins.CreateModelMixin,GenericAPIView)
ListAPIView(mixins.ListModelMixin,GenericAPIView)
RetrieveAPIView(mixins.RetrieveModelMixin,GenericAPIView)
DestroyAPIView(mixins.DestroyModelMixin,GenericAPIView)
UpdateAPIView(mixins.UpdateModelMixin,GenericAPIView)
ListCreateAPIView(mixins.ListModelMixin,mixins.CreateModelMixin,GenericAPIView)
RetrieveUpdateAPIView(mixins.RetrieveModelMixin,mixins.UpdateModelMixin,GenericAPIView)
RetrieveDestroyAPIView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,GenericAPIView)
RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,GenericAPIView) 终极的两个(二级封装更加方便了)
ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet)
其他都有, 只能读取
ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet)
全部都有, 集合了所有的请求方式 视图继承的选择
一阶段
View 你这是在用 django
二阶段
APIView 在用 drf 了.但是是最基础的方式
三阶段
GenericAPIView 很多参数可以用了, 但是所有方法自己写
四阶段
GenericAPIView + mixins 能用参数了, 不用写各请求的逻辑了. 但是还要写个壳子
五阶段
GenericAPIView + generics.xxx 能用参数, 而且灵活组合自己的请求类型, 壳子也不用写了
六阶段
GenericViewSet + generics.xxx 能用参数, 灵活组请求类型, 重写了as_view, 获得高级路由功能
七阶段
ReadOnlyModelViewSet 前面有的我都有. 但是我只能读
八阶段
ModelViewSet 我全都有
"""
路由
完全自定义路由
单数据,全数据的两只路由加 带格式的两只路由一共4条路由
# http://127.0.0.1:8000/api/v1/auth/
url(r'^auth/$', views.AuthView.as_view()),
# http://127.0.0.1:8000/api/v1/auth.json # 想要让页面显示json格式
url(r'^auth\.(?P<format>[a-z0-9]+)$', views.AuthView.as_view()),
# http://127.0.0.1:8000/api/v1/auth/1/
url(r'^auth/(?P<pk>\d+)/$', views.AuthView.as_view()),
# http://127.0.0.1:8000/api/v1/auth/1.json
url(r'^auth/(?P<pk>\d+)\.(?P<format>[a-z0-9]+)$', views.AuthView.as_view()), class AuthView(views.APIView): def get(self,request,*args,**kwargs):
return Response('...')
半自动路由
重写了 as_view 方法后,可以在as_view方法中加入参数传递方法对应,手动指定响应方式和视图方法的映射
url(r'^index/$', views.IndexView.as_view({'get':'list','post':'create'})),
url(r'^index\.(?P<format>[a-z0-9]+)$', views.IndexView.as_view({'get':'list','post':'create'})),
url(r'^index/(?P<pk>\d+)/$', views.IndexView.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),
url(r'^index(?P<pk>\d+)\.(?P<format>[a-z0-9]+)$', views.IndexView.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})), class IndexView(viewsets.ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = IndexSerializer
pagination_class = P2
全自动路由
完全自动生成所有的 url,且自动创建了视图关系
# 注册前的准备,做一个实例化对象
routers=routers.DefaultRouter()
# 注册需要加两个参数 ("url前缀",视图函数)
routers.register("authors",views.AuthorModelView)
routers.register("books",views.AuthorModelView)
"""
会自动帮你生成 4 条 url
^authors/$ [name='author-list']
^authors\.(?P<format>[a-z0-9]+)/?$ [name='author-list']
^authors/(?P<pk>[^/.]+)/$ [name='author-detail']
^authors/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='author-detail'] # 响应器控制
""" urlpatterns = [
# url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),
# url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"), # 上面的两条被简化成了下面一句话
url(r'', include(routers.urls)),
]
router = DefaultRouter()
router.register('index',views.IndexViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
] class IndexViewSet(viewsets.ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = IndexSerializer
pagination_class = P2 class IndexSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__"
rest framework 视图,路由的更多相关文章
- Django Rest Framework 视图和路由
Django Rest Framework 视图和路由 DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们 ...
- python 全栈开发,Day96(Django REST framework 视图,django logging配置,django-debug-toolbar使用指南)
昨日内容回顾 1. Serializer(序列化) 1. ORM对应的query_set和ORM对象转换成JSON格式的数据 1. 在序列化类中定义自定义的字段:SerializerMethodFie ...
- [Django REST framework - 视图组件之视图基类、视图扩展类、视图子类、视图集]
[Django REST framework - 视图组件之视图基类.视图扩展类.视图子类.视图集] 视图继承关系 详图见文章末尾 视图组件可点我查看 两个视图基类:APIView.GenericAP ...
- Django REST framework - 视图
目录 Django REST framework 视图GenericAPIView GenericAPIView 例子 属性 混入 具体视图类 自定义基类 Django REST framework ...
- 03 Django REST Framework 视图和路由
01-DRF中的request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别 ...
- rest framework之路由组件
一.路由组件的使用 1.使用实例 在视图中继承GenericViewSet类来完成功能时,需要自己对路由的写法有所改变,需要在as_view中传入actions字典参数: re_path('books ...
- Django 学习之Rest Framework 视图相关
drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. Django REST ...
- python框架之Django(4)-视图&路由
视图 负责接收请求和返回响应 FBV和CBV FBV FBV(function base views) 就是在视图里使用函数处理请求. from django.conf.urls import url ...
- Django-RestFrameWork之分页 视图 路由 渲染器
目录 一.分页 二.视图 三.路由 四.渲染器 一.分页 试问如果当数据量特别大的时候,你是怎么解决分页的? 方式a.记录当前访问页数的数据id 方式b.最多显示120页等 方式c.只显示上一页,下一 ...
随机推荐
- spring注解的相关配置
一.<context:annotation-config> 和 <context:component-scan> <context:annotation-config&g ...
- #WEB安全基础 : HTML/CSS | 文章索引
本系列讲解WEB安全所需要的HTML和CSS #WEB安全基础 : HTML/CSS | 0x0 我的第一个网页 #WEB安全基础 : HTML/CSS | 0x1初识CSS #WEB安全基础 : H ...
- Dvna for Owasp top 10 2017
简介: DVNA(Damn Vulnerable Node Application),它是一款由Node.js打造的知名WEB漏洞测试平台,或许有些朋友已经使用过.它是用来给使用Node的WEB开发人 ...
- SAP MM 实施项目里Open PO 迁移思路探讨
SAP MM 实施项目里Open PO 迁移思路探讨 .序言. SAP项目上线前夕,除了静态主数据需要导入以外,可能还有一些动态数据,比如open的采购订单,open的销售订单等单据也要迁移到SA ...
- [ArcGIS API for JavaScript 4.8] Sample Code-Get Started-widgets简介
[官方文档:https://developers.arcgis.com/javascript/latest/sample-code/intro-widgets/index.html] 一.Intro ...
- windows下QT打包
1.找到对应的MinGW命令,打开 2.进入exe目录 3.执行windeployqt XX.exe
- spring学习总结——装配Bean学习二(JavaConfig装配bean)
通过Java代码装配bean 前言:上面梳理了通过注解来隐式的完成了组件的扫描和自动装配,下面来学习下如何通过显式的配置的装配bean: 使用场景:比如说,你想要将第三方库中的组件装配到你的应用中,在 ...
- LeetCode算法题-Construct String from Binary Tree(Java实现)
这是悦乐书的第273次更新,第288篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第141题(顺位题号是606).构造一个字符串,该字符串由二叉树中的括号和整数组成,并具 ...
- linux安装成功后怎么调出终端
一.Ubuntu 桌面如下,点击搜索 二.输入terminal 终端 三.锁定到菜单栏 四.接下来就可以练习linux下的常用命令,如:ls mkdir cat touch 等等 这些命令后 ...
- Unknown column 'user_uid' in 'field list' sql错误解决过程
在idea中运行一直有错,找了好多个地方都找不到,以为是我的字段名字写错了,然而都是对的. 把错误的这个字段删了再打一遍就好了,