解析模块

为什么要配置解析模块

1)drf给我们提供了多种解析数据包方式的解析类
2)我们可以通过配置,来控制前台提交的哪些格式的数据后台在解析,哪些数据不解析
3)全局配置就是针对每一个视图类,局部配置就是针对指定的视图类,让它们可以按照配置规则选择性解析数据

源码入口

# APIView类的dispatch方法中
request = self.initialize_request(request, *args, **kwargs) # 点进去

# 获取解析类
parsers=self.get_parsers(), # 点进去

# 去类属性(局部配置) 或 配置文件(全局配置) 拿 parser_classes
return [parser() for parser in self.parser_classes]

全局配置:settings.py

REST_FRAMEWORK = {
# 全局解析配置
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser', # 解析json数据包
'rest_framework.parsers.FormParser', # 解析urlencoded数据包
'rest_framework.parsers.MultiPartParser' # 解析from-data数据包
],
}

局部配置:应用views.py的具体视图类

from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
class Book(APIView):
# 局部解析配置
parser_classes = [JSONParseer] # 只解析json数据包
def get(self, request, *args, **kwargs):
...
def post(self, request, *args, **kwargs):
# url拼接参数 : 只有一种传参方式,参数都在query_params
print(request.query_params) # <QueryDict: {'pk': ['1']}>
# 数据包参数 : 有三种传参方式 form-data,urlencoded,json,参数都在data
print(request.data) # <QueryDict: {'title': ['ha'], 'price': ['3.33']}>
return Response('post ok')
补充:
# 禁用 json 方法传输数据包时用json传输数据则报一下错误
{
"detail": "Unsupported media type \"application/json\" in request."
}
# 禁用 urlencoded 方法传输数据包时用urlencoded传输数据则报一下错误
{
"detail": "Unsupported media type \"application/x-www-form-urlencoded\" in request."
}
# 禁用 form-data 方法传输数据包时用form-data传输数据则报一下错误
{
"detail": "Unsupported media type \"multipart/form-data; boundary=--------------------------159319842159734003915314\" in request."
}

异常模块

为什么要自定义异常模块

1)所有经过drf的APIView视图类产生的异常,都可以提供异常处理方案
2)drf默认提供了异常处理方案(rest_framework.views.exception_handler),但是处理范围有限
3)drf提供的处理方案两种,处理了返回异常现象,没处理返回None(后续就是服务器抛异常给前台)
4)自定义异常的目的就是解决drf没有处理的异常,让前台得到合理的异常信息返回,后台记录异常具体信息 ps:ORM查询时的错误drf不会自动处理

源码分析

# 异常模块:APIView类的dispatch方法中
response = self.handle_exception(exc) # 点进去

# 获取处理异常的句柄(方法)
# 一层层看源码,走的是配置文件,拿到的是rest_framework.views的exception_handler
# 自定义:直接写exception_handler函数,在自己的配置文件配置EXCEPTION_HANDLER指向自己的
exception_handler = self.get_exception_handler()

# 异常处理的结果
# 自定义异常就是提供exception_handler异常处理函数,处理的目的就是让response一定有值
response = exception_handler(exc, context)

如何使用:

全局配置: settings.py

REST_FRAMEWORK = {
# 全局配置异常模块
'EXCEPTION_HANDLER': 'api.exception.exception_handler', # api为应用名
}

应用文件下创建exception.py

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
from rest_framework import status

def exception_handler(exc, context):
# 1.先让drf的exception_handler做基础处理,拿到返回值
# 2.若有返回值则drf处理了,若返回值为空说明drf没处理,需要我们手动处理
response = drf_exception_handler(exc, context)
print(exc) # 错误内容 'NoneType' object has no attribute 'title'
print(context)
# {'view': <api.views.Book object at 0x000001BBBCE05B00>, 'args': (), 'kwargs': {'pk': '3'}, 'request': <rest_framework.request.Request object at 0x000001BBBCF33978>}
print(response)
# 返回值为空,做二次处理
if response is None:
print('%s - %s - %s' % (context['view'], context['request'].method, exc))
# <api.views.Book object at 0x00000242DC316940> - GET - 'NoneType' object has no attribute 'title'
return Response({
'detail': '服务器错误'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
return response

响应模块

响应类构造器:rest_framework.response.Response

def __init__(self, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None):
"""
:param data: 响应数据
:param status: http响应状态码
:param template_name: drf也可以渲染页面,渲染的页面模板地址(不用了解)
:param headers: 响应头
:param exception: 是否异常了
:param content_type: 响应的数据格式(一般不用处理,响应头中带了,且默认是json)
"""
pass

使用:常规实例化响应对象

# status就是解释一堆 数字 网络状态码的模块
from rest_framework import status就是解释一堆 数字 网络状态码的模块
# 一般情况下只需要返回数据,status和headers都有默认值
return Response(data={数据}, status=status.HTTP_200_OK, headers={设置的响应头})

自定义响应模块

responses.py

from rest_framework.response import Response

class APIResponse(Response):
def __init__(self, data_status=0, data_msg='ok', results=None, http_status=None, headers=None, exception=None, **kwargs):
# data的初始状态: 状态码与状态信息
data = {
'status': data_status,
'msg':data_msg
}
# data的响应数据体: results (其可能是False,0等数据, 这些数据某些情况下也会作为合法数据返回)
if results is not None:
data['results'] = results
# data响应的其他内容:
# if kwargs is not None:
# for k, v in kwargs.items():
# setattr(data, k, v)
data.update(kwargs)
super().__init__(data=data, status=http_status, headers=headers, exception=exception)

drf框架 - 解析模块 | 异常模块 | 响应模块的更多相关文章

  1. DRF框架(二)——解析模块(parsers)、异常模块(exception_handler)、响应模块(Response)、三大序列化组件介绍、Serializer组件(序列化与反序列化使用)

    解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 form-data/urlencoded/json 2)我们可以通过配置来控制前台提交的哪些格式的数据后台在解析,哪些 ...

  2. DRF框架中的异常处理程序

    目录 DRF框架中自定义异常处理 一.自定义异常的原因 二.如何设置处理异常的程序 DRF框架中自定义异常处理 一.自定义异常的原因 在Django和DRF框架中都封装了很多的处理异常的程序,可以处理 ...

  3. DRF框架中csrf异常

    一.报错信息 "detail": "CSRF Failed: CSRF cookie not set." 二.解决办法 方法一: 在配置文件中配置 REST_F ...

  4. DRF框架和Vue框架阅读目录

    Vue框架目录 (一)Vue框架(一)——Vue导读.Vue实例(挂载点el.数据data.过滤器filters).Vue指令(文本指令v-text.事件指令v-on.属性指令v-bind.表单指令v ...

  5. 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)

    目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...

  6. 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)

    一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...

  7. drf解析模块,异常模块,响应模块,序列化模块

    复习 """ 1.接口:url+请求参数+响应参数 Postman发送接口请求的工具 method: GET url: https://api.map.baidu.com ...

  8. drf框架的解析模块-异常处理模块-响应模块-序列化模块

    解析模块 为什么要配置解析模块 (1).drf给我们通过了多种解析数据包方式的解析类. (2).我们可以通过配置来控制前台提交的那些格式的数据台解析,那些数据不解析. (3).全局配置就是针对一个视图 ...

  9. django-rest-framework-源码解析002-序列化/请求模块/响应模块/异常处理模块/渲染模块/十大接口

    简介 当我们使用django-rest-framework框架时, 项目必定是前后端分离的, 那么前后端进行数据交互时, 常见的数据类型就是xml和json(现在主流的是json), 这里就需要我们d ...

随机推荐

  1. 设置Kafka集群的方法

    1.目标 今天,在这篇Kafka文章中,我们将看到Kafka Cluster Setup.这个Kafka集群教程为我们提供了一些设置Kafka集群的简单步骤.简而言之,为了实现Kafka服务的高可用性 ...

  2. CF28B pSort

    题目描述 给定一个含有n个元素的数列,第i号元素开始时数值为i,元素i可以与距离为d[i]的元素进行交换.再给定一个1-n的全排列,问初始的数列可否交换成给定的样式. 输入:第一行一个整数n,第二行n ...

  3. Vue框架 03

    Vue项目开发: 前后端完全分离 后端:提供接口数据 前端:页面转跳.页面布局.页面数据渲染全部由前端做 中间交互:请求 搭建Vue项目环境: Vue项目需要自建服务器:node node介绍: 1. ...

  4. Codeforces Round #567 Div. 2

    A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 ...

  5. vue 项目之后生成的 dist 文件该怎么在本地启动运行

    简单高效 npm i -g servecd distserve

  6. 斐波那契数列(递归)c#

    我郑重宣布 我爱递归 我自己编程几乎都没用过递归 我看到这个题的时候虽然想到了用递归 但是我个脑残一直在想怎么设置动态数组 明明纯递归更简单 我也是可无语 反正我爱上递归了 爱惹  无法自拔

  7. DDL和DML 的区别

    DDL (Data Definition Language 数据定义语言) create table 创建表 alter table 修改表 drop table 删除表 truncate table ...

  8. gitlab用户登录与AD域用户集成

    ---恢复内容开始--- 编辑gitlab.rb文件 sudo vi /etc/gitlab/gitlab.rb 下图是我编辑的内容示例(仅供参考): 编辑以下内容: gitlab_rails['ld ...

  9. 入门Docker,你要下载什么?注册什么?

    此随笔根据前人经验改编并亲自实践.遇到问题提供出相应解决方法. 入门Docker,你要下载什么?注册什么? Docker.app你肯定是要下载的!此教程应用于MAC系统PC不保证适用 Docker f ...

  10. 9.如何让一个div 上下左右居中?【CS

      方法1:[绝对定位50%-本身50%]              position:absolute; left:50%; top:50%;              transform: tra ...