视图

  在上面序列化的组件种已经用到了视图组件,即在视图函数部分进行逻辑操作。

  但是很明显的弊端是,对每个表的增删改查加上 单条数据,需要用到 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 视图,路由的更多相关文章

  1. Django Rest Framework 视图和路由

    Django Rest Framework 视图和路由   DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们 ...

  2. python 全栈开发,Day96(Django REST framework 视图,django logging配置,django-debug-toolbar使用指南)

    昨日内容回顾 1. Serializer(序列化) 1. ORM对应的query_set和ORM对象转换成JSON格式的数据 1. 在序列化类中定义自定义的字段:SerializerMethodFie ...

  3. [Django REST framework - 视图组件之视图基类、视图扩展类、视图子类、视图集]

    [Django REST framework - 视图组件之视图基类.视图扩展类.视图子类.视图集] 视图继承关系 详图见文章末尾 视图组件可点我查看 两个视图基类:APIView.GenericAP ...

  4. Django REST framework - 视图

    目录 Django REST framework 视图GenericAPIView GenericAPIView 例子 属性 混入 具体视图类 自定义基类 Django REST framework ...

  5. 03 Django REST Framework 视图和路由

    01-DRF中的request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别 ...

  6. rest framework之路由组件

    一.路由组件的使用 1.使用实例 在视图中继承GenericViewSet类来完成功能时,需要自己对路由的写法有所改变,需要在as_view中传入actions字典参数: re_path('books ...

  7. Django 学习之Rest Framework 视图相关

    drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. Django REST ...

  8. python框架之Django(4)-视图&路由

    视图 负责接收请求和返回响应 FBV和CBV FBV FBV(function base views) 就是在视图里使用函数处理请求. from django.conf.urls import url ...

  9. Django-RestFrameWork之分页 视图 路由 渲染器

    目录 一.分页 二.视图 三.路由 四.渲染器 一.分页 试问如果当数据量特别大的时候,你是怎么解决分页的? 方式a.记录当前访问页数的数据id 方式b.最多显示120页等 方式c.只显示上一页,下一 ...

随机推荐

  1. 【Dojo 1.x】笔记目录

    学习笔记和教程是不同的,笔记是随心记,学到什么就写什么,我尽量按逻辑顺序写笔记. Dojo是什么? Dojo是这么一个JavaScript框架,区别于jQuery等小型类库,这个类库更合适于构建Web ...

  2. Vs2017 无法调试APP

      其实一切都是扯,看看有没有主活动吧 症状:能部署安装,没有快捷方式,不启动调试.XARAMIN不能在XML中配置主活动,会自动根据[Activity(Label = "AA", ...

  3. word表格转html后去除冗余代码

    word可以另存为html文件,通过这个功能,可以快速实现网页展示word内容,特别是表格的编辑,它包含tr.td.th.rowspan.colspan等内容,直接写比较繁琐. 但word转换过来的h ...

  4. centos服务器如何监控访问ip,并将非法ip通过防火墙禁用

    centos服务器如何监控访问ip,并将非法ip通过防火墙禁用 上周给朋友帮忙,上架了一款小游戏(年年有鱼),项目刚一上线,就遇到了ddos攻击,阿里云连续给出了6次ddos预警提示,服务器一度处于黑 ...

  5. 算法: 整数中1出现的次数(从1到n整数中1出现的次数)

    问题: 整数中1出现的次数(从1到n整数中1出现的次数) 问题:求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数? 为此他特别数了一下1~13中包含1的数字有1.10.11 ...

  6. linux快捷进入长目录的方法

    快捷命令   :alias chaoyang ='cd /usr/lib/uu/hh/lib' 1.将上述设置写到家目录的.bashrc文件中(~/.bashrc) 2.然后source ./bash ...

  7. SQL Server 索引碎片产生原理重建索引和重新组织索引

    数据库存储本身是无序的,建立了聚集索引,会按照聚集索引物理顺序存入硬盘.既键值的逻辑顺序决定了表中相应行的物理顺序 多数情况下,数据库读取频率远高于写入频率,索引的存在 为了读取速度牺牲写入速度 页 ...

  8. centos下Django+uwsgi+nginx

    本篇章主要讲解uwsgi和nginx的作用,并利用两者对django项目进行部署 一.概述 在开发过程中,我们一般是在该项目的虚拟环境中启用django自带的web服务:python manage.p ...

  9. JavaScript -- JSON.parse 函数 和 JSON.stringify 函数

    JavaScript -- JSON.parse 函数 和 JSON.stringify 函数 1. JSON.parse 函数: 使用 JSON.parse 可将 JSON 字符串转换成对象. &l ...

  10. Thread中的join()方法

    package com.qjc.thread; public class JoinExcemple { // join方法就是用来同步的 public static void main(String[ ...