Rest framework-解析器组件

Rest framework-解析器组件

解析器就是解析的数据

为什么REST的request.data可以解析JSON,form-data,urlencoding数据,因为他默认的解析器有这几种

Rest framework-解析器组件_第1张图片
image.png

局部 优先于 全局 优先于 默认

局部

# views.py

from rest_framework.parsers import JSONParser,FormParser
from app01.models import Course
class CourseView(APIView):
    # 不写parser_classes默认选中所有解析器
    # parser_classes指定用那几个解析器
    parser_classes = [JSONParser,]

    def get(self,request):
        return HttpResponse("get....")

    def post(self,request):
        print(request.data)
        return HttpResponse("post.....")

全局

如果局部没有定义的话,他就会去他继承的父类APIView里面去找

# APIView

class APIView(View):

    # The following policies may be set at either globally, or per-view.
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
    # parser_classes 局部没定义就 api_settings 里边找
    parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
    content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
    metadata_class = api_settings.DEFAULT_METADATA_CLASS
    versioning_class = api_settings.DEFAULT_VERSIONING_CLASS

# ..............等
# 生成一个实例方法
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
# 所以这里就是一个对象点一个属性 (APIView)
# api_settings没有DEFAULT_RENDERER_CLASSES属性
# 对象点一个没有的属性的时候就会触发__getattr__
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES

对象点一个没有的属性的时候就会触发__getattr__

# 先看__getattr__方法
# 因为对象点一个没有的属性的时候就会触发__getattr__
# __getattr__中会调用user_settings,然后在看user_settings函数
class APISettings(object):      
    def __init__(self, user_settings=None, defaults=None, import_strings=None):
        if user_settings:
            self._user_settings = self.__check_user_settings(user_settings)
        self.defaults = defaults or DEFAULTS
        self.import_strings = import_strings or IMPORT_STRINGS
        self._cached_attrs = set()

    @property
    def user_settings(self):
        if not hasattr(self, '_user_settings'):
                        # 去settings下面找REST_FRAMEWORK,找不到就返回空字典
            # 相当于取到了值,就用取到的,否则就用默认的
            self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
        return self._user_settings

    # 对象点一个没有的属性的时候就会触发__getattr__
    # api_settings没有DEFAULT_RENDERER_CLASSES属性,所以会调用__getattr__方法
    def __getattr__(self, attr):
        # attr就是api_settings.DEFAULT_RENDERER_CLASSES的DEFAULT_RENDERER_CLASSES
        if attr not in self.defaults:
            # DEFAULT_RENDERER_CLASSES 又不存在所以不会执行这句
            raise AttributeError("Invalid API setting: '%s'" % attr)

        try:
            # 检查在用户设置中是否存在。调用user_settings函数
            val = self.user_settings[attr]
        except KeyError:
            # 用户设置中是不存在则回到默认值
            # self.defaults[attr]=self.DEFAULTS[DEFAULT_PARSER_CLASSES]
            val = self.defaults[attr]

        # Coerce import strings into classes
        if attr in self.import_strings:
            val = perform_import(val, attr)

        # Cache the result
        self._cached_attrs.add(attr)
        setattr(self, attr, val)
        return val
       # ...............  等

所以在去settings下面设置下REST_FRAMEWORK就为全局的

# 只允许
REST_FRAMEWORK={
    'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
            # 'rest_framework.parsers.FormParser',
            # 'rest_framework.parsers.MultiPartParser'
        ),
}

这时候你再去以非JSON数据去访问任何网站内的数据的时候request.data解析时都会返回error

# urlencoded数据去访问放回的错误
{
    "detail": "Unsupported media type \"application/x-www-form-urlencoded\" in request."
}

默认

# 共传了三个参数(None, DEFAULTS, IMPORT_STRINGS)
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)

# APISettings __init__初始化的时候有这条
self.defaults = defaults or DEFAULTS
# 以下是APISettings单独拿出来参考的数据
# 解析后自己理解转换后的
# self.defaults[attr]=self.DEFAULTS[DEFAULT_PARSER_CLASSES]
val = self.defaults[attr]
return val

# 下面我们就来找DEFAULTS里边的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'
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication'
    ),
    
    # ...............  等
}

你可能感兴趣的:(Rest framework-解析器组件)