Django REST Framework 学习笔记(二):请求模块 request

  • Title(EN): Django REST Framework Learning Notes (2): the request module
  • Author: dog2

DRF请求生命周期流程

  1. 根据应用中urls.py,走as_view方法,但是视图类没有该方法,所以请求走的是APIViewas_view方法
  2. APIViewas_view调用父类(django原生View)的as_view,同时还禁用了 csrf 认证
  3. 在父类(django原生View)的as_viewdispatch方法请求走的又是APIViewdispatch
    • 因为APIView也可以走dispatch,视图类是先继承APIViewAPIView中没有再去原生View
  4. 完成任务方法交给视图类的请求函数处理,得到请求的响应结果,返回给前台

因此直接从APIView的dispatch入口看源码。

请求模块

基本信息

  • 源码:rest_framework.request
    • rest_framework.request.Request:主要类
  • 官方文档:API Guide - Requests

源码分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 在`APIView`类的`dispatch`方法中,二次封装request (请求模块)
request = self.initialize_request(request, *args, **kwargs) #点进去

#点击查看Request源码
return Request(
  request,
  ...
)

# 在rest_framework.request.Request实例化方法中
self._request = request #将原生request作为drf request的_request属性

# 在rest_framework.request.Request的__getattr__方法中
try:
return getattr(self._request, attr) # 访问属性完全兼容原生request
except AttributeError:
return self.__getattribute__(attr)

总结

  1. drf 对原生request做了二次封装,设置request._request等于原生request
  2. 原生request对象的属性和方法都可以被drf的request对象直接访问(兼容)
  3. drf请求的所有url拼接参数均被解析到query_params中,所有数据包数据都被parser解析到data
    • get请求:url中拼接的参数通过request.query_params获取
    • post请求:所有请求方式所携带的数据包都是通过request.data获取

用法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Test(APIView):
def get(self, request, *args, **kwargs):
# url拼接的参数
print(request._request.GET) # 二次封装方式
print(request.GET) # 兼容
print(request.query_params) # 拓展

return Response('drf get ok')

def post(self, request, *args, **kwargs):
# 所有请求方式携带的数据包
print(request._request.POST) # 二次封装方式
print(request.POST) # 兼容
print(request.data) # 拓展,兼容性最强,三种传参方式都可以:form-data,urlencoding,json

print(request.query_params)

return Response('drf post ok')