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/165774.html原文链接:https://javaforall.net

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


相关推荐

  • 关于程序多开的尝试。CreateMutex,OpenMuxtex,ReleaseMutex「建议收藏」

    关于程序多开的尝试。CreateMutex,OpenMuxtex,ReleaseMutex「建议收藏」因为偶尔会遇到对那些不能支持双开的程序进行多开。。根据前一阵转的一篇文件了解到,现在大多程序都用CreateMutex方式来限制多开,于是有个想法:它Create了,我Release它,然后不就可以多开了吗?然而。。。经过一些小程序的验证及网上的搜索,我失败了。原因是:对于一个Mutex来说,只有Create它的进程才可以Release它。所以想用这种方式是不可能了。不过并不是…

    2022年6月26日
    26
  • msfconsole 控制台使用和操作[通俗易懂]

    msfconsole 控制台使用和操作[通俗易懂]Msfconsole提供了一个一体化的集中控制台。通过msfconsole,你可以访问和使用所有的metasploit的插件,payload,利用模块,post模块等等。Msfconsole还有第三方程序的接口,比如nmap,sqlmap等,可以直接在msfconsole里面使用。在启动MSF终端之后,可以首先输入help命令列出MSF终端所支持的命令列表,包括核心命令集和后端数据库命令集。对于…

    2025年9月27日
    3
  • 【Pycharm】Pycharm专业版 社区版 教育版区别「建议收藏」

    【Pycharm】Pycharm专业版 社区版 教育版区别「建议收藏」因为刚接触python,对pythonIDE不够了解,通过各方面的查找对比最终还是选择了pycharm,对于新手来说社区版的功能足够满足需求。还可以使用sublimetext编译器(好像是收费的)进行代码编译,还有很多我这边就不一一列举了。附上PyCharm官网链接pycharm下载这篇博客来记录介绍一下pycharm各个版本的区别pycharm是一专注于python的集成开发环境,…

    2022年8月25日
    9
  • sublime text3配置ctrl+鼠标左键进行函数跳转「建议收藏」

    sublime text3配置ctrl+鼠标左键进行函数跳转「建议收藏」点击Preferences->BrowsePackages进入Packages目录,然后打开User目录,查看User目录里面有没有Default(Windows).sublime-mousemap文件,如果没有则创建一个。这个文件是用来配置sublime的鼠标操作的。在文件中输入如下内容:[ { “button”:”button2″, “count”:1, “m…

    2022年7月11日
    112
  • gzip和gunzip 解压参数「建议收藏」

    gzip和gunzip 解压参数「建议收藏」Linux压缩保留源文件的方法:gzip–cfilename>filename.gzLinux解压缩保留源文件的方法:gunzip–cfilename.gz>filenamegunzip的用法  1.作用gunzip命令作用是解压文件,使用权限是所有用户。2.格式gunzip[-acfhlLnNqrtvV][-s-Linux压缩保留源文件的方法: g…

    2025年8月27日
    8

发表回复

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

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