Django(49)drf解析模块源码分析[通俗易懂]

Django(49)drf解析模块源码分析[通俗易懂]前言上一篇分析了请求模块的源码,如下:definitialize_request(self,request,*args,**kwargs):"""Retu

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

上一篇分析了请求模块的源码,如下:

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格式的数据,那么就需要局部配置
 

局部配置

默认全局配置是因为我们写的视图继承自APIViewAPIView中配置了类属性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.net/166135.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • react中父组件向子组件传值

    react中父组件向子组件传值1.子组件代码:定义props.属性名来接收父组件传递过来的值importReact,{Component}from”react”;exportdefaultclassSonextendsComponent{render(){return<div>我是子组件—{this.props.text}</div>;}}2.父组件代码:在引用子组件时,在子组件身上传递数据(用子组件定义的属性来传递)importR

    2022年5月27日
    34
  • 零基础python从入门到精通(Python从入门到项目实践 吾爱破解)

    文章目录强烈推荐系列教程,建议学起来!!一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置4.2手动添加镜像源4.3永久配置镜像源五.插件安装(比如汉化?)5.1自动补码神器第一款5.2汉化pycharm5.3其它插件六.美女背景七.自定义脚本开头八、这个前言一定要看九、python入门十、python缩进十一、Python注释1.单行注释2.多行注释十二、Python变量1.变量定义理解2.变量名命名3.分

    2022年4月17日
    69
  • STL源码解析之vector自实现

    1.vector实现框架2.空间配置器空间配置器方面的内容在之前的博客已进行详细说明,查看->STL空间配置器解析和实现.3.内存基本处理工具(1)对象构造(2)Destroy(

    2021年12月28日
    35
  • C语言经典算法100例(一)

    C语言经典算法100例(一)C语言中有有许多经典的算法,这些算法都是许多人的智慧结晶,也是编程中常用的算法,这里面包含了众多算法思想,掌握这些算法,对于学习更高级的、更难的算法都会有很大的帮助,会为自己的算法学习打下坚实的基础。 接下来我们先来看10道:  (1)输出9*9乘法口诀。 //9*9乘法口诀表voidTable99(){ inti,j; for(i=1;i<=9;i+

    2022年5月1日
    51
  • Java Eclipse自动补全设置[通俗易懂]

    Java Eclipse自动补全设置[通俗易懂]Eclipse代码自动补全功能默认只包括点”.” ,即只有输入”.”后才出现自动补全的提示框。想要自动补全总是去按“Alt+/”也很麻烦。其实只需简单在Eclipse中进行设置即可实现输入任意及符合自动出现自动补全提示框。具体设置步骤如下:   选择Eclipse菜单条中的Windows菜单下的Preferences项。在左侧找到“Java”=》“Editor”=》

    2022年6月28日
    19
  • 第一篇提问艺术「建议收藏」

    第一篇提问艺术「建议收藏」虽然这是老话常谈,但是最近的回答问题的过程中,有点感触。你问题问的好,问的准确,回答你的人才有积极性给你答复,这样你又可以更快的解决你的问题。好多人不知道如何提问,所以我打算把这篇老文章转过来置顶。花点时间看看。如果没时间,至少看看下面的图吧:====================================================================

    2022年6月23日
    22

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号