Django(49)drf解析模块源码分析[通俗易懂]
大家好,又见面了,我是你们的朋友全栈君。
前言
上一篇分析了请求模块的源码,如下:
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
上述源码中parsers=self.get_parsers()
就是解析模块源码的入口
源码分析
我们点击get_parsers
进入查看该方法
def get_parsers(self):
"""
Instantiates and returns the list of parsers that this view can use.
"""
return [parser() for parser in self.parser_classes]
该方法实例化并返回此视图可以使用的解析器列表,我们点击parser_classes
,查看解析器列表
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
我们会发现解析器列表,是从api_settings
中的DEFAULT_PARSER_CLASSES
查找的,而api_settings
又等于APISettings
中的DEFAULTS
,我们可以从settings
中的DEFAUITS
列表的DEFAULT_PARSER_CLASSES
,如下:
DEFAULTS = {
# Base API policies
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
],
}
我们可以看到,drf默认的解析器列表中有3个解析器,这3个解析器中都有media_type
属性,代表支持解析的数据提交类型
- JSONParser:
media_type = 'application/json'
- FormParser:
media_type = 'application/x-www-form-urlencoded'
- MultiPartParser:
media_type = 'multipart/form-data'
如果我们想在以上3个解析器的基础上,再加上文件类型的解析器,那么需要全局配置。
全局配置
我们可以在settings.py
文件中设置REST_FRAMEWORK
配置,具体设置如下:
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
'rest_framework.parsers.FileUploadParser'
],
}
这样,我们以后所有继承于APIView
的类视图都可以解析上面配置的4种数据类型,但是如果我们想某个视图只能解析json
格式的数据,那么就需要局部配置
局部配置
默认全局配置是因为我们写的视图继承自APIView
,APIView
中配置了类属性parser_classes
,所以我们自己编写的视图函数中,也设置个类属性,并且导入JSONParser
解析器
from rest_framework.parsers import JSONParser
class TestView(APIView):
# 局部解析类配置
parser_classes = [JSONParser]
def post(self, request, *args, **kwargs):
print(request.data)
return Response("drf post ok")
接着我们使用application/x-www-form-urlencoded
提交数据,会有如下报错
{
"detail": "不支持请求中的媒体类型 “application/x-www-form-urlencoded”。"
}
然后我们使用multipart/form-data
提交数据,也会报错
{
"detail": "不支持请求中的媒体类型 “multipart/form-data; boundary=--------------------------022567055086460827891894”。"
}
最后我们使用application/json
提交数据,响应成功
"drf post ok"
自定义解析器
如果我们想自定义一个解析器,也很简单,默认的3个解析器都继承自BaseParser
,我们查看下源码
class BaseParser:
"""
All parsers should extend `BaseParser`, specifying a `media_type`
attribute, and overriding the `.parse()` method.
"""
media_type = None
def parse(self, stream, media_type=None, parser_context=None):
"""
Given a stream to read from, return the parsed representation.
Should return parsed data, or a `DataAndFiles` object consisting of the
parsed data and files.
"""
raise NotImplementedError(".parse() must be overridden.")
如果我们需要自定义解析器,那么就必须继承自BaseParser
,并且设置属性media_type
,还要重写parse
方法,有需求的小伙伴可以自行尝试,这里就不演示了
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/166135.html原文链接:https://javaforall.cn
相关文章
- Python进阶34-Django 中间件
- django pycharm_pycharm调试django
- Django(75)django-rest-framework-simplejwt「建议收藏」
- Django中的form表单校验
- Django 教程_最简单剪花朵的步骤
- Django框架开发001期 Python+Django开发教程,开启你的第一个django网站应用
- django 警告 while time zone support is active
- 【Django】在大型项目中的django的性能模型字段primary_key
- Django的中间件之一
- Django+Celery学习笔记4——django+celery+redis周期任务Crontabs设置
- Django登录页面优化
- Sentry 错误监控(Django 错误监控)
- django 2.2 管理后台添加找回密码功能
- django inclusion_tag 包含标签
- django2.2 + mysql + pymysql: django.db.utils.InternalError: (1366, "Incorrect string value 解决方案
- 错误:django.db.utils.OperationalError: no such column: django_celery_results_taskresult.hidden
- python-Django-Django 模板引擎(一)
- Django Rest Framework源码剖析(五)—–解析器详解编程语言
- Django Rest Framework源码剖析(一)—–认证详解编程语言
- Django的模板继承详解编程语言
- Django基础学习七之如何配置django+mysql详解编程语言
- Django基础学习五_引入静态文件详解编程语言
- Django基础学习一详解编程语言
- 使用AJAX获取Django后端数据
- 深入浅出Django与MSSQL整合(django-mssql)