首页 > 其他分享 >解析器

解析器

时间:2023-10-21 14:34:51浏览次数:31  
标签:解析器 type self parser request ._ data

解析器本质行是解析请求发过来的数据


一个解析就是一个类
class Form解析器

  • content-type:'urlencode...'

class Json解析器

  • content-type:'application/Json'
  • def parse(self...):
    • ...

请求者
GET
http://127.0.0.1:8000/api/home/?xxx=123&=xxx
请求头 键值对 ....
POST
http://127.0.0.1:8000/api/home/?xxx=123&=xxx -->request.query_perams
请求头
请求体 name="haha"&age=19
json:{"name":"haha","age":19}
针对请求体,进行解析。
1. 读取请求头
2.根据请求头解析数据
- - 根据请求头获取解析器 ->根据解析类挑选出对应的解析器
- - json解析器.parse 解析出来赋值给了 reuqets.data
- - 然后执行request.data


解析器的应用
--常用的也是Json解析器,可以处理复杂的逻辑关系。
image
image


源码分析

class Request:
    """
    Wrapper allowing to enhance a standard `HttpRequest` instance.

    Kwargs:
        - request(HttpRequest). The original request instance.
        - parsers(list/tuple). The parsers to use for parsing the
          request content.
        - authenticators(list/tuple). The authenticators used to try
          authenticating the request's user.
    """

    def __init__(self, request, parsers=None, authenticators=None,
                 negotiator=None, parser_context=None):
        assert isinstance(request, HttpRequest), (
            'The `request` argument must be an instance of '
            '`django.http.HttpRequest`, not `{}.{}`.'
            .format(request.__class__.__module__, request.__class__.__name__)
        )

        self._request = request
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        self.negotiator = negotiator or self._default_negotiator()
        self.parser_context = parser_context
        self._data = Empty
        self._files = Empty
        self._full_data = Empty
        self._content_type = Empty
        self._stream = Empty

        if self.parser_context is None:
            self.parser_context = {}
        self.parser_context['request'] = self
        self.parser_context['encoding'] = request.encoding or settings.DEFAULT_CHARSET

        force_user = getattr(request, '_force_auth_user', None)
        force_token = getattr(request, '_force_auth_token', None)
        if force_user is not None or force_token is not None:
            forced_auth = ForcedAuthentication(force_user, force_token)
            self.authenticators = (forced_auth,)

    @property
    def data(self):
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
        return self._full_data
    def _load_data_and_files(self):
        """
        Parses the request content into `self.data`.
        """
        if not _hasattr(self, '_data'):
            self._data, self._files = self._parse()
            if self._files:
                self._full_data = self._data.copy()
                self._full_data.update(self._files)
            else:
                self._full_data = self._data

            # if a form media type, copy data & files refs to the underlying
            # http request so that closable objects are handled appropriately.
            if is_form_media_type(self.content_type):
                self._request._post = self.POST
                self._request._files = self.FILES
    def _parse(self):
        """
        Parse the request content, returning a two-tuple of (data, files)

        May raise an `UnsupportedMediaType`, or `ParseError` exception.
        """
        media_type = self.content_type
        try:
            stream = self.stream
        except RawPostDataException:
            if not hasattr(self._request, '_post'):
                raise
            # If request.POST has been accessed in middleware, and a method='POST'
            # request was made with 'multipart/form-data', then the request stream
            # will already have been exhausted.
            if self._supports_form_parsing():
                return (self._request.POST, self._request.FILES)
            stream = None

        if stream is None or media_type is None:
            if media_type and is_form_media_type(media_type):
                empty_data = QueryDict('', encoding=self._request._encoding)
            else:
                empty_data = {}
            empty_files = MultiValueDict()
            return (empty_data, empty_files)

        parser = self.negotiator.select_parser(self, self.parsers)

        if not parser:
            raise exceptions.UnsupportedMediaType(media_type)

        try:
            parsed = parser.parse(stream, media_type, self.parser_context)
        except Exception:
            # If we get an exception during parsing, fill in empty data and
            # re-raise.  Ensures we don't simply repeat the error when
            # attempting to render the browsable renderer response, or when
            # logging the request or similar.
            self._data = QueryDict('', encoding=self._request._encoding)
            self._files = MultiValueDict()
            self._full_data = self._data
            raise

        # Parser classes may return the raw data, or a
        # DataAndFiles object.  Unpack the result as required.
        try:
            return (parsed.data, parsed.files)
        except AttributeError:
            empty_files = MultiValueDict()
            return (parsed, empty_files)


class APIView(View):
    def perform_content_negotiation(self, request, force=False):
        """
        Determine which renderer and media type to use render the response.
        """
        renderers = self.get_renderers()
        conneg = self.get_content_negotiator()

        try:
            return conneg.select_renderer(request, renderers, self.format_kwarg)
        except Exception:
            if force:
                return (renderers[0], renderers[0].media_type)
            raise
    def initial(self, request, *args, **kwargs):
        """
        Runs anything that needs to occur prior to calling the method handler.
        """
        self.format_kwarg = self.get_format_suffix(**kwargs)

        # Perform content negotiation and store the accepted info on the request
        neg = self.perform_content_negotiation(request)
        request.accepted_renderer, request.accepted_media_type = neg

        # Determine the API version, if versioning is in use.
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme

        # Ensure that the incoming request is permitted
        self.perform_authentication(request)
        self.check_permissions(request)
        self.check_throttles(request)
    def get_parser_context(self, http_request):
        """
        Returns a dict that is passed through to Parser.parse(),
        as the `parser_context` keyword argument.
        """
        # Note: Additionally `request` and `encoding` will also be added
        #       to the context by the Request object.
        return {
            'view': self,
            'args': getattr(self, 'args', ()),
            'kwargs': getattr(self, 'kwargs', {})
        }
    def initialize_request(self, request, *args, **kwargs):
        """
        Returns the initial request object.
        """
        parser_context = self.get_parser_context(request)

        return Request(
            request,								#django的request,这些全部封装到了request对象中了
            parsers=self.get_parsers(),              #解析器的对象 调用了这两的对象 [JSONParser(), FormParser()]
            authenticators=self.get_authenticators(),#认证组件 认证对象
            negotiator=self.get_content_negotiator(),#这个调用的是我class中的DefaultContentNegotiation的对象
            parser_context=parser_context			# {视图对象,url路由的参数
        )
    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            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
		
class ApiView(APIView):
    versioning_class = URLPathVersioning
    parser_classes = [JSONParser, FormParser]
    content_negotiation_class = DefaultContentNegotiation

    def get(self, request,*args,**kwargs):
        print(request.version)
        print(request.versioning_scheme)
        url = request.versioning_scheme.reverse("hh",request=request)
        print("反向生成url:", url)
        return Response("......")

    def post(self,request,*args,**kwargs):
        print(request.data)
        self.dispatch()
        return Response("ok")

------------

标签:解析器,type,self,parser,request,._,data
From: https://www.cnblogs.com/bxj123/p/17778916.html

相关文章

  • 好用的C语言JSON解析器
    本文介绍开源C语言库Melon的JSON解析器。相信很多读者都听说过甚至使用过cJSON开源库。那么本文就拿cJSON与Melon的JSON组件进行对比。下面我们就来一起看一看。编码Encode假设我们要构建如下JSON:{"name":"Awesome4K","resolutions":[{"w......
  • springmvc中设置文件的上传与下载,首先需要导入依赖,之后需要在springmvc.xml中配置问价
    2023-09-16导入依赖<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency>设置文件上传解析器springmvc.xml<?xml......
  • DRF----分页、路由、解析器
    1.5djangorestframework(下)drf内置了很多便捷的功能,在接下来的课程中会给大家依次讲解下面的内容:快速上手请求的封装版本管理认证权限限流序列化视图条件搜索分页路由解析器  10.分页在查看数据列表的API中,如果数据量比较大,肯定......
  • python argparse—用于命令行选项、参数和子命令的解析器
    参考:https://docs.python.org/3/library/argparse.htmlargparse.ArgumentParser:创建Parser对象语法格式class argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-......
  • solr中如何定义自己的解析器插件(QParserPlugin)
    /*****************************************************/>solr中如何定义自己的解析器插件/*****************************************************/0.为什么要自定义自己的解析器插件/*****************************************************///因为solr默认的Lucen......
  • 【CJsonObject】C++ JSON 解析器使用教程
    能选封装的尽量不使用底层的一、CJsonObject简介CJsonObject是Bwar基于cJSON全新开发一个C++版的JSON库。CJsonObject的最大优势是轻量、简单好用,开发效率极高,尤其对多层嵌套json的读取和生成、修改极为方便。CJsonObject比cJSON简单易用得多,且只要不是有意不......
  • HandlerMethodArgumentResolver方法参数解析器的使用
    一、使用场景介绍HandlerMethodArgumentResolver,中文称为方法参数解析器,是SpringWeb(SpringMVC)组件中的众多解析器之一,主要用来对Controller中方法的参数进行处理。在一般的接口调用场景下,每次调用Controller都需要检查请求中的token信息,并根据token还原用户信息,然后将用户信息封......
  • 【cJSON】轻量级的C语言JSON解析器
    1.JSON与cJSONJSON——轻量级的数据格式JSON全称JavaScriptObjectNotation,即JS对象简谱,是一种轻量级的数据格式。它采用完全独立于编程语言的文本格式来存储和表示数据,语法简洁、层次结构清晰,易于人阅读和编写,同时也易于机器解析和生成,有效的提升了网络传输效率。JSON......
  • python:python解析器和pycharm编译器安装
    python解析器下载地址:https://www.python.org/getit/注意事项:1.建议下载3.6以以上的版本,2.官网下载比较慢,可以自行寻找其它网站下载,3.建议使用.exe安装包方式下载安装 下载完成后双击运行     验证是否安装成功:  pycharm编译器下载......
  • fnt文件解析器
     用于解析BMFont软件生成的fnt文件 usingSystem;usingSystem.Collections.Generic;usingSystem.Text.RegularExpressions;usingUnityEngine;publicclassFntParse{publicstructKerning{publicintfirst;publicintsecond;......