简介

Django Rest Framework是一个强大且灵活的工具包,主要用以构建RESTful风格的Web API。

Django REST Framework(简称DRF)可以在Django的基础上迅速实现API,并且自身还带有 基于WEB的测试和浏览页面,可以方便的测试自己的API。DRF几乎是Django生态中进行前后端 分离开发的默认库。

Django REST Framework具有以下功能和特性:

  • 自带基于Web的可浏览的API,对于开发者非常有帮助
  • 支持OAuth1a 和OAuth2认证策略
  • 支持ORM或非ORM数据源的序列化
  • 高可自定制性,多种视图类型可选
  • 自动生成符合 RESTful 规范的 API 支持
  • OPTION、HEAD、POST、GET、PATCH、PUT、DELETE等HTTP方法
  • 根据 Content-Type 来动态的返回数据类型(如HTML、json)
  • 细粒度的权限管理(可到对象级别)
  • 丰富的文档和强大的社区支持
  • Mozilla、Red Hat、 Heroku和Eventbrite等知名公司正在使用

安装

在项目环境中直接pip安装

pip install djangorestframework

安装完毕,在项目配置文件中,注册app:

INSTALLED_APPS = (
...
'rest_framework',
)

如果你想使用基于浏览器的可视化的API目录,并且希望获得一个登录登出功能,那么可以在根 路由下添加下面的路由('api-auth/' 可以随意指定),这个功能类似Django自带的admin后台:

urlpatterns = [
...
path('api-auth/', include('rest_framework.urls'))
]

为了登录操作,也许你还要生成数据表,创建超级用户。

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

DRF模块

DRF有几大功能模块:

  1. 序列化模块(Serializer): (rest_framework.serializers) 对数据进行序列化和反序列化, 序列化即通过django的model对象创建序列化对象, 进而将对应的字段转换为json格式, 反序列化即通过请求中的json数据创建反序列化对象, 进而将json数据转化为字典格式, 序列化模块中提供了常用的三种序列化类:

    1.1 Serializer类(rest_framework.serializers.Serializer): 基础的序列化类, 需要自己编写所有的字段以及create和update方法,比较底层,抽象度较低

    1.2 ModelSerializer类(rest_framework.serializers.ModelSerializer): 更常用的序列化类, 不需要手动编写所有字段, 会根据指向的model自动生成默认的字段和简单的create和update方法

    1.3 ListSerializer类(rest_framework.serializers.ListSerializer): 当使用ModelSerializer进行群改(一次更新多个model对象)时, 需要用到ListSerializer并重写update()方法

  2. 请求模块(Request): (rest_framework.request.Request) 对django的原生request对象进行二次封装, 将原生request对象封装至DRF自己的Request的_request属性中, 并新增了解析器, 认证器等属性

  3. 解析模块(Parses) : (rest_framework.parser) 对request中携带的常见Content-Type进行相应的解析:

    3.1 JSONParser类(rest_framework.parser.JSONParser): 解析Content-Type为 application/json 的数据

    3.2 FormParser类(rest_framework.parser.FormParser): 解析Content-Type为 application/x-www-form-urlencoded 的数据(普通form表单提交的数据)

    3.3 MultiPartParser类(rest_framework.parser.MultiPartParser): 解析Content-Type为 multipart/form-data 的数据(比普通form表单支持的类型更多)

    3.4 FileUploadParser类(rest_framework.parser.FileUploadParser): 解析Content-Type为 */* 的数据, 一般为文件类型的数据

  4. 认证模块(Authentication): (rest_framework.authentication) 对request进行验证, 判断请求的用户是否合法, 一般将用户分成三类: 游客(不携带认证信息的匿名用户), 非法用户(携带了认证信息的用户但信息是错误的), 合法用户(携带了正确的认证信息)

  5. 权限模块(Permission): (rest_framework.permission) 对通过认证的用户判断其是否有权限访问该页面

  6. 频率模块(Throttle): (rest_framework.throttling) 限制同一个访问客户端的IP或用户等指标每秒访问服务器的次数

  7. 响应模块(Response): (rest_framework.response) 将序列化后的数据以及其他常见response数据如http状态码/headers等封装成Response对象

  8. 异常模块(Exception): (rest_framework.exceptions) 捕获认证模块/权限模块/频率模块/自定义视图类/响应模块中所抛出的异常, 并将异常信息转化为json返回给前端

  9. 渲染模块(Renders): (rest_framework.renderers) 返回json数据还是将数据渲染为HTML页面等

DRF源码入口

rest_framework.views.as_view()

使用DRF时, 需要将视图文件(view.py)定义的类(CBV)继承rest_framework的APIView(APIView是django原生View的子类)或者将定义的函数(FBV)用rest_framework的api_view装饰器进行装饰. 因此在url中调用的view.as_view()方法或者api_view中调用的as_view方法就是rest_framework.views.as_view()方法, 即rest_framework重写了django原生的view中的as_view()方法

    @classmethod
def as_view(cls, **initkwargs):
"""
Store the original class on the view function. This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
"""
代码省略......# 1.调用父类View的as_view
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs # 2.跳过csrf认证
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)

分析as_view()方法, 发现其主要做了两件事: 1. 调用父类View的as_view  2. 跳过csrf认证

因此主要的逻辑还是在父类View的as_view中, 来到父类View.as_view的代码, 发现其定义了一个view方法, 最后返回这个view方法, 在view方法中实例化了一个cls的对象(self), 然后返回了self.dispatch方法的返回值

    @classonlymethod
def as_view(cls, **initkwargs):
"""Main entry point for a request-response process."""
     代码省略......
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.setup(request, *args, **kwargs)
if not hasattr(self, 'request'):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
return self.dispatch(request, *args, **kwargs)
代码省略......return view

rest_framework.views.dispatch()

注意上面的cls就是as_view的cls参数, 也就是外层APIView中的as_view的cls参数, 也就是APIView, 那么这里cls创建的self就是APIView的对象, 那么调用的dispatch方法就是APIView对象的dispatch方法, 如果我们自定义的视图类没有重写dispatch方法, 那么就会走APIView的dispatch方法, 可以看到APIView中确实重写了dispatch方法, 这里就是DRF的核心入口

    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) # 通过反射获取自定义视图类中request.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

在这个dispatch中主要分为了5部分

1.  request = self.initialize_request(request, *args, **kwargs) 这里初始化了一个DRF的Request对象, 除了包括了django原生request, 还包括了解析器, 权限器等

2.  self.initial(request, *args, **kwargs) 这里是对Request进行三大校验, 包括认证模块(authentication), 权限模块(permission), 频率模块(throttle)

3.  response = handler(request, *args, **kwargs) 这里是先通过反射机制获取自定义视图类中request.method对应的方法, 然后调用该方法, 得到处理结果

4.  response = self.handle_exception(exc) 这里是捕获三大校验和获取响应所抛出的异常, 并得到异常的处理结果

5.  self.response = self.finalize_response(request, response, *args, **kwargs) 这里将上面的到的正常或异常处理结果(response)再进行最终的渲染处理, 可以渲染为单纯的json数据或者是方便浏览器查看的html格式等

django-rest-framework-源码解析001-整体框架的更多相关文章

  1. Django Rest Framework源码剖析(八)-----视图与路由

    一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使 ...

  2. Django Rest Framework源码剖析(三)-----频率控制

    一.简介 承接上篇文章Django Rest Framework源码剖析(二)-----权限,当服务的接口被频繁调用,导致资源紧张怎么办呢?当然或许有很多解决办法,比如:负载均衡.提高服务器配置.通过 ...

  3. [源码解析] 并行分布式框架 Celery 之架构 (1)

    [源码解析] 并行分布式框架 Celery 之架构 (1) 目录 [源码解析] 并行分布式框架 Celery 之架构 (1) 0x00 摘要 0x01 Celery 简介 1.1 什么是 Celery ...

  4. [源码解析] 并行分布式框架 Celery 之架构 (2)

    [源码解析] 并行分布式框架 Celery 之架构 (2) 目录 [源码解析] 并行分布式框架 Celery 之架构 (2) 0x00 摘要 0x01 上文回顾 0x02 worker的思考 2.1 ...

  5. [源码解析] 并行分布式框架 Celery 之 worker 启动 (1)

    [源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 0x00 摘要 0x01 Celery的架 ...

  6. [源码解析] 并行分布式框架 Celery 之 worker 启动 (2)

    [源码解析] 并行分布式框架 Celery 之 worker 启动 (2) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (2) 0x00 摘要 0x01 前文回顾 0x2 ...

  7. [源码解析] 并行分布式框架 Celery 之 容错机制

    [源码解析] 并行分布式框架 Celery 之 容错机制 目录 [源码解析] 并行分布式框架 Celery 之 容错机制 0x00 摘要 0x01 概述 1.1 错误种类 1.2 失败维度 1.3 应 ...

  8. AspNetCore3.1_Secutiry源码解析_8_Authorization_授权框架

    目录 AspNetCore3.1_Secutiry源码解析_1_目录 AspNetCore3.1_Secutiry源码解析_2_Authentication_核心流程 AspNetCore3.1_Se ...

  9. [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle

    [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle 目录 [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Ming ...

  10. django之admin源码解析

    解析admin的源码 第一步:项目启动,加载settings文件中的 INSTALLED_APPS 里边有几个app就加载几个,按照注册顺序来执行. 第二步:其中加载的是admin.py,加载每一个a ...

随机推荐

  1. c语音学习笔记

    1.学习教程参考了杨光福 android jni Android视频<JNI> http://edu.csdn.net/course/detail/3235/54186?auto_star ...

  2. SSH网上商城一

    Java高级项目之SSH网上商城项目实战: 1.采用目前最主流的三大框架开发即Struts2+Spring+Hibernate框架整合开发.2.通过AJAX技术提供良好的用户体验.3.提供了邮箱激活的 ...

  3. caffe的python接口学习(1)生成配置文件

    ---恢复内容开始--- 看了denny的博客,写下自己觉得简短有用的部分 想用caffe训练数据首先要学会编写配置文件: (即便是用别人训练好的模型也要进行微调的,所以此关不可跨越) 代码就不粘贴了 ...

  4. 基于jQuery的打字机函数

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. WTL中GDI+支持资源文件加载

    WTL中GDI+支持资源文件加载 分类: WTL WTL gdi+ gdi+2013-04-22 17:16 78人阅读 评论(0) 收藏 举报 WTLGDI+c++ 今天遇到一个小问题困扰了.就是G ...

  6. 《UNIX环境高级编程》(APUE) 笔记第四章 - 文件和目录

    4 - 文件和目录 1. 函数 stat.fstat.fstatat 和 lstat #inlcude <sys/stat.h> int stat(const char *restrict ...

  7. 小师妹学JVM之:逃逸分析和TLAB

    目录 简介 逃逸分析和栈上分配 TLAB简介 TLAB详解 设置TLAB空间的大小 TLAB中大对象的分配 TLAB空间中的浪费 总结 简介 逃逸分析我们在JDK14中JVM的性能优化一文中已经讲过了 ...

  8. Appium移动端自动化测试--搭建模拟器和真机测试环境

    详细介绍安装Android Studio及Android SDK.安装Appium Server. 文章目录如下 目录 文章目录如下 模拟器--安装Android Studio及Android SDK ...

  9. web单页应用是什么?它的好处与坏处有哪些(如何解决这些缺点)

    web单页应用是什么? Web单页应用就是指只有一个Web页面作为入口的应用,在浏览器中运行期间不会重新加载页面.也就是说浏览器一开始会加载它必需的thml.css和Js,之后所有的交互操作都在一个页 ...

  10. 如何针对 iPhone X 设计网站?

    在全面屏的 iPhone X 上,不需要而外的代码,Safari 可以非常完美的展示现有的网站.整个网站的内容都会自动地展示在一个“安全区域”内,并不会被四周的圆角或者“小刘海”遮挡住. Safari ...