解析模块
解析模块
一 、源解析器的作用
根据请求头content-type
选择对应的解析器对请求体内容进行处理。有application/json
,x-www-form-urlencoded
,form-data
等格式
二 、源全局使用解析器
-
settings.py
配置
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser'
'rest_framework.parsers.FormParser'
'rest_framework.parsers.MultiPartParser'
]
}
-
urls.py
配置
urlpatterns = [
url(r'test/', TestView.as_view()),
]
-
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class TestView(APIView):
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
"""
application/x-www-form-urlencoded 或
multipart/form-data时,request.POST中才有值
"""
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
三 、源局部使用解析器
3.1 content-type为application/json
-``urls.py`
from django.conf.urls import url, include
from web.views.s5_parser import TestView
urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
-
views.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser
class TestView(APIView):
parser_classes = [JSONParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
"""
application/x-www-form-urlencoded 或
multipart/form-data时,request.POST中才有值
"""
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
3.2 content-type为application/x-www-form-urlencoded
-
urls.py
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
-
views.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import FormParser
class TestView(APIView):
parser_classes = [FormParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
"""
application/x-www-form-urlencoded 或
multipart/form-data时,request.POST中才有值
"""
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
3.3 content-type为multipart/form-data
urls.py
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
-
views.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import MultiPartParser
class TestView(APIView):
parser_classes = [MultiPartParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
"""
application/x-www-form-urlencoded 或
multipart/form-data时,request.POST中才有值
"""
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
-
templete.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img">
<input type="submit" value="提交">
</form>
</body>
</html>
3.4 仅上传文件
-
urls.py
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'),
]
-
views.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import FileUploadParser
class TestView(APIView):
parser_classes = [FileUploadParser, ]
def post(self, request, filename, *args, **kwargs):
print(filename)
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
"""
application/x-www-form-urlencoded 或
multipart/form-data时,request.POST中才有值
"""
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
-
templete.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img">
<input type="submit" value="提交">
</form>
</body>
</html>
3.5 同时多个Parser
当同时使用多个parser时,rest framework会根据请求头content-type自动进行比对,并使用对应parser
-
urls.py
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
-
views.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
class TestView(APIView):
parser_classes = [JSONParser, FormParser, MultiPartParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
"""
application/x-www-form-urlencoded 或
multipart/form-data时,request.POST中才有值
"""
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
四 、源码分析
4.1 request解析
"""
1 在调用request.data时,才进行解析,由此入手
"""
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
"""
2 查看self._load_data_and_files()方法
---->
self._data, self._files = self._parse()
"""
def _parse(self):
#用户请求头里content_type的值
media_type = self.content_type
"""
self.parsers 就是用户配置的
parser_classes=[FileUploadParser,FormParser]
"""
#self里就有content_type,传入此函数
parser = self.negotiator.select_parser(self,
self.parsers)
"""
3 查看self.negotiator.select_parser(self, self.parsers)
"""
def select_parser(self, request, parsers):
"""同过media_type和request.content_type比较,
来返回解析器,然后调用解析器的解析方法"""
# 每个解析器都有media_type = 'multipart/form-data'属性
for parser in parsers:
if media_type_matches(
parser.media_type,
request.content_type):
return parser
return None
"""
4 最终调用parser的解析方法来解析
parsed = parser.parse(stream,
media_type,
self.parser_context)
"""
4.2 request实例化
# 1 Request实例化,parsers=self.get_parsers()
Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
# 2 get_parsers方法,循环实例化出self.parser_classes中类对象
def get_parsers(self):
return [parser() for parser in self.parser_classes]
# 3 self.parser_classes 先从类本身找,找不到去父类找即APIVIew 中的
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
# 4 api_settings是一个对象,对象里找DEFAULT_PARSER_CLASSES属性,
# 找不到,会到getattr方法
def __getattr__(self, attr):
if attr not in self.defaults:
raise AttributeError(
"Invalid API setting: '%s'" % attr
)
try:
# 调用self.user_settings方法,
# 返回一个字典,字典再取attr属性
val = self.user_settings[attr]
except KeyError:
# Fall back to defaults
val = self.defaults[attr]
# Coerce import strings into classes
if attr in self.import_strings:
val = perform_import(val, attr)
# Cache the result
self._cached_attrs.add(attr)
setattr(self, attr, val)
return val
"""
5 user_settings方法 ,通过反射去setting配置
文件里找REST_FRAMEWORK属性,找不到,返回空字典
"""
@property
def user_settings(self):
if not hasattr(self, '_user_settings'):
self._user_settings = getattr(settings,
'REST_FRAMEWORK',
{}
)
return self._user_settings
4.1 jQuery安装
>: cnpm install jquery
4.2 vue/cli 3 配置 jQuery
在vue.config.js
中配置(没有,手动项目根目录下新建)
const webpack = require("webpack");
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
Popper: ["popper.js", "default"]
})
]
}
};
4.3 BootStrap安装
>: cnpm install bootstrap
4.4 vue/cli 3 配置BootStrap
在main.js
中配置
import "bootstrap"
import "bootstrap/dist/css/bootstrap.css"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现