Django REST Framework 请求封装源码解析与实现流程

版本说明:

Django: V4.2.20

Django Rest Framework: V3.15.2


一、核心封装流程示意图

客户端请求 Django路由匹配 调用APIView.as_view 创建APIView实例 执行dispatch方法 initialize_request封装 创建DRF Request对象 执行认证/权限检查 处理请求方法 构建Response对象

二、源码实现解析

1. 请求封装入口(APIView.dispatch)

python 复制代码
# rest_framework/views.py
class APIView(View):
    def dispatch(self, request, *args, ​**kwargs):
        # 将原生request封装为DRF Request对象
        request = self.initialize_request(request, *args, ​**kwargs)
        self.request = request  # 替换原生request对象
        
        try:
            # 执行认证/权限校验
            self.initial(request, *args, ​**kwargs)
            # 调用对应的HTTP方法处理器
            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

2. Request对象初始化源码

python 复制代码
# rest_framework/request.py
class Request:
    def __init__(self, request, parsers=None, authenticators=None):
        self._request = request  # 存储原生Django请求对象
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        self._data = Empty  # 延迟加载请求体数据
        
    @property
    def data(self):
        # 统一解析不同格式的请求体
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
        return self._full_data
    
    def __getattr__(self, attr):
        # 代理访问原生request属性,此处不同的版本可能代码有差异,逻辑是一致的
        try:
            _request = self.__getattribute__("_request")
            return getattr(_request, attr)
        except AttributeError:
            return self.__getattribute__(attr)

三、关键实现原理

1. 请求数据统一处理

DRF通过Parser解析器类自动处理不同Content-Type的请求数据:

  • 表单数据:request.POST → request.data
  • JSON数据:自动解析为字典格式
  • 文件上传:request.FILES → request.data

2. 属性访问代理机制

通过__getattr__方法实现属性穿透访问:

python 复制代码
# 访问原生request的method属性
drf_request.method → drf_request._request.method

# 访问原生request的GET参数
drf_request.query_params → drf_request._request.GET

3. 请求处理流程优化

python 复制代码
# 传统Django视图
def view(request):
    json_data = json.loads(request.body)  # 需要手动解析
    # 业务处理...

# DRF视图
class APIView(APIView):
    def post(self, request):
        data = request.data  # 自动解析后的数据
        # 直接使用结构化数据

四、完整封装流程图解

属性存在 属性不存在 存在 不存在 客户端发起请求 Django路由匹配 创建APIView实例 调用dispatch方法 initialize_request封装 创建DRF Request对象 存储原生request到_request属性 访问DRF Request属性 直接返回属性值 触发__getattr__方法 代理访问原生request属性 属性存在性检查 返回原生request属性 抛出AttributeError

五、开发注意事项

  1. ​避免直接访问原生request,应通过request._request访问原生对象
  2. 自定义解析器配置,在settings.py中配置:
python 复制代码
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser'
    ]
}
  1. 请求方法扩展
    DRF Request新增方法:
python 复制代码
request.query_params  # 替代request.GET
request.user          # 通过认证后的用户对象
request.auth          # 认证令牌等凭证信息

六、性能优化建议

  1. ​减少重复数据解析,对频繁访问的request.data进行缓存

  2. 选择性禁用解析器,在视图级别指定解析器:

python 复制代码
class MyAPI(APIView):
    parser_classes = [JSONParser]
  1. 批量请求处理,使用drf-flex-fields等扩展库优化大数据量请求

通过上述封装机制,DRF实现了:

  • 请求处理逻辑标准化
  • 不同数据格式的统一访问接口
  • 认证/权限系统的无缝集成
  • 开发者体验的大幅提升
相关推荐
张人玉9 小时前
基于 Vue2 + ECharts + Express + SQLite 的南阳市专题数据可视化系统
sqlite·echarts·express
hanxiuchao3 天前
告别客户端臃肿!网页端 M3U8 播放调试方案,适配全办公场景
运维·python·django·m3u8·m3u8播放
程序员羽痕3 天前
基于深度学习的眼疾识别系统
人工智能·pytorch·深度学习·分类·django
流云鹤3 天前
1. 配置环境、创建导航栏
python·django
流云鹤3 天前
2.登录模块
python·django
流云鹤4 天前
专题栏说明
python·django
XGeFei5 天前
【Django学习笔记】—— Django 高并发通俗讲解
笔记·学习·django
weixin_BYSJ19875 天前
springboot美食食谱小程序---附源码24044
java·spring boot·python·spring cloud·django·tomcat·php
Xiangchu_5 天前
合肥新能源汽车崛起,本地硅胶件谁来供
python·算法·eclipse·sqlite·汽车·制造
Quincy_Freak5 天前
Python 轻量化数据存储实践:国产化环境下SQLite高效管理方案
数据库·sqlite·数据库管理·大数据分析·sqlitego