django-rest-framework-源码解析001-整体框架
简介
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-整体框架的更多相关文章
- Django Rest Framework源码剖析(八)-----视图与路由
一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使 ...
- Django Rest Framework源码剖析(三)-----频率控制
一.简介 承接上篇文章Django Rest Framework源码剖析(二)-----权限,当服务的接口被频繁调用,导致资源紧张怎么办呢?当然或许有很多解决办法,比如:负载均衡.提高服务器配置.通过 ...
- [源码解析] 并行分布式框架 Celery 之架构 (1)
[源码解析] 并行分布式框架 Celery 之架构 (1) 目录 [源码解析] 并行分布式框架 Celery 之架构 (1) 0x00 摘要 0x01 Celery 简介 1.1 什么是 Celery ...
- [源码解析] 并行分布式框架 Celery 之架构 (2)
[源码解析] 并行分布式框架 Celery 之架构 (2) 目录 [源码解析] 并行分布式框架 Celery 之架构 (2) 0x00 摘要 0x01 上文回顾 0x02 worker的思考 2.1 ...
- [源码解析] 并行分布式框架 Celery 之 worker 启动 (1)
[源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 0x00 摘要 0x01 Celery的架 ...
- [源码解析] 并行分布式框架 Celery 之 worker 启动 (2)
[源码解析] 并行分布式框架 Celery 之 worker 启动 (2) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (2) 0x00 摘要 0x01 前文回顾 0x2 ...
- [源码解析] 并行分布式框架 Celery 之 容错机制
[源码解析] 并行分布式框架 Celery 之 容错机制 目录 [源码解析] 并行分布式框架 Celery 之 容错机制 0x00 摘要 0x01 概述 1.1 错误种类 1.2 失败维度 1.3 应 ...
- AspNetCore3.1_Secutiry源码解析_8_Authorization_授权框架
目录 AspNetCore3.1_Secutiry源码解析_1_目录 AspNetCore3.1_Secutiry源码解析_2_Authentication_核心流程 AspNetCore3.1_Se ...
- [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle
[源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle 目录 [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Ming ...
- django之admin源码解析
解析admin的源码 第一步:项目启动,加载settings文件中的 INSTALLED_APPS 里边有几个app就加载几个,按照注册顺序来执行. 第二步:其中加载的是admin.py,加载每一个a ...
随机推荐
- 技术干货丨卷积神经网络之LeNet-5迁移实践案例
摘要:LeNet-5是Yann LeCun在1998年设计的用于手写数字识别的卷积神经网络,当年美国大多数银行就是用它来识别支票上面的手写数字的,它是早期卷积神经网络中最有代表性的实验系统之一.可以说 ...
- SpringBoot--swagger搭建、配置及使用
一. 作用: 1. 接口的文档在线自动生成. 2. 接口测试. 二.模块介绍 Swagger是一组开源项目,其中主要要项目及功能如下: 1.Swagger Codegen: 通过Codegen 可以将 ...
- Scrapy框架简介及小项目应用
今天来总结一下Scrapy框架的用法.scrapy的架构如下: Engine :引擎,处理整个系统的数据流处理.触发事务,是整个框架的核心. Items :项目,它定义了爬取结果的数据结构,爬取的数 ...
- c++数字转化为字符串、字符串转换为数字
char ch[20]; int i =1; int j = 2; char *p = "34567"; 数字装换为字符串 sprintf(ch , "%d,%d&quo ...
- ES11来了,还学得动吗?
写在前面 ES2020(即 ES11)上周(2020 年 6 月)已经正式发布,在此之前进入 Stage 4 的 10 项提案均已纳入规范,成为 JavaScript 语言的新特性 一.特性一览 ES ...
- 断路器Hystrix(Feign)
上一篇中我们讲了 断路器Hystrix(Ribbon) 本章讲解Feign+Hystrix已经Request请求传递,各种奇淫技巧…. - Hystrix Hystrix支持回退概念:当 断路器 打开 ...
- PL/SQL 美化器&规则解释&优化代码
前言 PLSQL有非常强大的自定义设置功能,比如美化文件规则, 使用者可以自行定义编辑规则,以便更好的优化SQL语句,增加可读性. 例如以下的部分代码,又长,分段不好,空格太多,结构散乱,还没有注释. ...
- elasticsearch7.6 安装 并且开启外网访问,真的好累。
下载 下载页面 https://www.elastic.co/cn/downloads/elasticsearch wget https://artifacts.elastic.co/download ...
- spring和springmvc包扫描问题
写这篇博客之前,橘子松必须感慨下!!找了我一下午加一晚上(md),问了几个朋友也没找到.凉了啊 在搭建ssm之前,我把controller service mapper包扫描用基本包扫描 都写在a ...
- tomcat结合shiro无文件webshell的技术研究以及检测方法
0x01简介 shiro结合tomcat回显,使用公开的方法,回显大多都会报错.因为生成的payload过大,而tomcat在默认情况下,接收的最大http头部大小为8192.如果超过这个大小,则to ...