一、APIView

通过APIView实现API的过程如下:

urls.py

   url(r'^books/$', views.BookView.as_view(),name="books"),
url(r'^books/(\d+)/$', views.BookDetailView.as_view(),name="detailbook"),

views.py

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, context={'request': request})
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return Response(bs.errors) def delete(self, request, id):
Book.objects.filter(pk=id).delete() return Response()

urls中,定义了两个url的请求方式:

  • 通过URL:http://127.0.0.1/books/   GET/POST数据

  • 通过URL:http://127.0.0.1/books/id/   GET/PUT/DELETE数据

第一种,url(r'^books/$', views.BookView.as_view(),name="books"),调用过程如下:

views.BookView.as_view()

  1、APIView.as_view(),返回view,实际上是执行View.as_view()

    2、View中的as_view()返回disptch()函数

      3、self会从View类往上找dispatch(),在APIView类中有找到dispatch()

        4、dispatch()会找get、post、put、delete等方法

          5、在当前View下,BookView类下定义了get、post,BookDetailView类下定义了get、put、delete

            6、执行当前类下的对应方法

第二种URL执行过程一样。

二、ModelView

通过ModelView实现API过程如下:

urls.py

 url(r'^authors/$', views.AuthorModelView.as_view({'get':'list','post':'create'}),name="authors"),
url(r'^authors/$', views.AuthorModelView.as_view({'get':'retrieve','post':'update','delete':'destory'}),name="authors"),

views.py

class AuthorModelView(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
  

执行过程如下:

1、当前类下没有as_view方法,从父类ModelViewSet中查找


class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass

2、ModeViewSet在mixins中没有as_view,从GenericViewSet往上找


class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass

3、从ViewSetMixin中找到了as_view(),实际上返回了dispatch()

ViewSetMixin==>generics.GenericAPIView==>views.APIView==>dispatch()

4、执行dispatch(),实际上是找get、post、put、delete等方法

5、在当前类下找到对应的方法

三、认证、权限、频率源码

通过ModelView方式实现认证,

局部应用:

class AuthorModelView(viewsets.ModelViewSet):

    authentication_classes = [TokenAuth, ]
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
pagination_class = StandardResultsSetPagination

  

  

全局应用:

REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.utils.TokenAuth",], }

  

源码实现过程:

服务端以authors为例:

 1、在AuthorModelView中查找as_view(),在本类中找不到,往上查找;

 2、父类:viewsets.ModelViewSet

class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass

  3、其他几个父类没有as_view()和祖父类了,只能从GenericViewSet往上找;

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass

  4、最左边父类ViewSetMixin查找as_view(),找到了

  5、ViewSetMixin中的as_veiw()实际上返回了dispatch()

  6、再查找dispatch()方法,顺序:generics.GenericAPIView==>APIView==>dispatch()

  

    def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate? try:
self.initial(request, *args, **kwargs) # Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc:
response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

  7、dispatch()中,先会执行self.initial()

    def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)

  8、initial()中会对过来的请求进行认证、授权、频率检测。

图标流程如下:

  

REST-framework快速构建API--源码解析的更多相关文章

  1. 第三十四节,目标检测之谷歌Object Detection API源码解析

    我们在第三十二节,使用谷歌Object Detection API进行目标检测.训练新的模型(使用VOC 2012数据集)那一节我们介绍了如何使用谷歌Object Detection API进行目标检 ...

  2. 基于.NetCore的Redis5.0.3(最新版)快速入门、源码解析、集群搭建与SDK使用【原创】

    1.[基础]redis能带给我们什么福利 Redis(Remote Dictionary Server)官网:https://redis.io/ Redis命令:https://redis.io/co ...

  3. sqler sql 转rest api 源码解析(一)应用的启动入口

    sqler sql 转rest api 的源码还是比较简单的,没有比较复杂的设计,大部分都是基于开源 模块实现的. 说明: 当前的版本为2.0,代码使用go mod 进行包管理,如果本地运行注意gol ...

  4. sqler sql 转rest api 源码解析(四)macro 的执行

    macro 说明 macro 是sqler 的核心,当前的处理流程为授权处理,数据校验,依赖执行(include),聚合处理,数据转换 处理,sql 执行以及sql 参数绑定 授权处理 这个是通过go ...

  5. Redis系列(六):数据结构QuickList(快速列表)源码解析

    1.介绍 Redis在3.2版本之前List的底层编码是ZipList和LinkedList实现的 在3.2版本之后,重新引入了QuickList的数据结构,列表的底层都是QuickList实现 当L ...

  6. sqler sql 转rest api 源码解析(三) rest协议

    rest 服务说明 rest 协议主要是将配置文件中的宏暴露为rest 接口,使用了labstack/echo web 框架,同时基于context 模型 进行宏管理对象的共享,同时进行了一些中间件的 ...

  7. sqler sql 转rest api 源码解析(二) resp 协议

    resp 协议主要是方便使用redis 客户端进行连接,resp 主要是依赖 tidwall/redcon golang redis 协议包 resp 服务说明 server_resp.go 文件,干 ...

  8. 在Eclipse中关联Android API源码

    在Eclipse中快速关联API源码,便于查看类以及方法.方法如下: 1. 在对应的项目文件右键——>properties——>java build path——>libraries ...

  9. 第零章 dubbo源码解析目录

    第一章 第一个dubbo项目 第二章  dubbo内核之spi源码解析 2.1  jdk-spi的实现原理 2.2 dubbo-spi源码解析 第三章 dubbo内核之ioc源码解析 第四章 dubb ...

  10. Spring中AOP相关的API及源码解析

    Spring中AOP相关的API及源码解析 本系列文章: 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configuration注解? 谈谈Spring ...

随机推荐

  1. 离群点检测与序列数据异常检测以及异常检测大杀器-iForest

    1. 异常检测简介 异常检测,它的任务是发现与大部分其他对象不同的对象,我们称为异常对象.异常检测算法已经广泛应用于电信.互联网和信用卡的诈骗检测.贷款审批.电子商务.网络入侵和天气预报等领域.这些异 ...

  2. Windows批处理 -- 打造MySQLCleaner

    批处理打造MySQLCleaner 1. 简介       在我们卸载MySQL数据库的时候,往往除了需要卸载软件,还需要删除各种注册表信息,隐藏文件,卸载服务,否则当我们再次安装MySQL时就会出现 ...

  3. 【PAT】B1037 在霍格沃茨找零钱(20 分)

    #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int ...

  4. C++中的istringstream

    istringstream用于执行C++风格的串流操作. 下面的示例是使用一个字符串初始化istringstream类,然后再使用>>操作符来依次输出字符串中的内容. temp_mon=& ...

  5. 推荐5款简洁美观的Hexo主题

    2018-11-17 17:15:46 原文地址:http://www.izhongxia.com 以下是 <hexo 主题列表> 中挑选出来一些比较简洁美观的主题(存在个人主观意识,请勿 ...

  6. [笔记]后缀数组SA

    参考资料这次是真抄的: 1.后缀数组详解 2.后缀数组-学习笔记 3.后缀数组--处理字符串的有力工具 定义 \(SA\)排名为\(i\)的后缀的位置 \(rk\)位置为\(i\)的后缀的排名 \(t ...

  7. ROS教程1 消息查看和使用服务

    消息动态图 rqt_graph能够创建一个显示当前系统运行情况的动态图形. rosrun rqt_graph rqt_graph 如果你将鼠标放在/turtle1/command_velocity上方 ...

  8. docker官方文档学习-1-Docker for mac安装配置

    https://docs.docker.com/docker-for-mac/ Get started with Docker for Mac 首先像在本博客docker-1-环境安装及例子实践处将环 ...

  9. Echarts中太阳图(Sunburst)的实例

    Echarts中太阳图(Sunburst)的实例 目前在项目中要实现一个Echars中的太阳图,但是Echars中的太阳图的数据格式是一个树形结构,如下代码格式如下: var mapData = [ ...

  10. Objective-C atomic属性不是线程安全的

    atomic(原子的),顾名思义,原子操作应该是线程安全的,然而,真相并不是! @property (atomic, strong) NSMutableArray *arr; // 多线程操作arr并 ...