Rest framework-解析器组件
解析器就是解析的数据
为什么REST的request.data可以解析JSON,form-data,urlencoding数据,因为他默认的解析器有这几种
局部 优先于 全局 优先于 默认
局部
# 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'
),
# ............... 等
}