drf中的类为什么要继承APIVIEW:
在APIVIEW的dispatch中执行的initial方法:
initial函数中设置了实例化类中的三个校验:
1.perform_authentication(request) 身份校验
2.check_permissions(request) 权限校验
3.check_throttles(request) 访问频率校验
4.initialize_request重新封装了request为request添加了很多属性:
drf as_view() APIVIEW的流程分析,调用父类(VIEW)的as_view(),并执行dispatch()函数,但是APIVIEW中也有dispatch()这个方法,因此执行的是子类(APIVIEW)中的dispatch方法(why),是不是有个属性查找,我们定义一个Service类他继承于APIVIEW,它自身没有dispatch,他就到他的父类(APIVIEW)中找dispatch.
流程如下:
首先也是执行as_view(),调用父类的as_view,然后执行dispatch函数封装了request,dispatch中有三种校验认证,权限,频率
源码如下:
1.initialize_request重新封装了request
2.initial 认证,权限,频率
class APIView(View):
@classmethod
def as_view(cls, **initkwargs):
"""
Store the original class on the view function.
This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
"""
#如果
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)
cls.queryset._fetch_all = force_evaluation
view = super(APIView, cls).as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
#注释了中间件csrf
return csrf_exempt(view)
#APIVIEW,中的
#1.initialize_request重新封装了request
#2.initial
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对象,这样原来的request就不在了传入了parsers,authenticators,negotiator
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
#重新封装request对象通过Request
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
)
#initial函数中设置了实例化类中的三个校验:
#1.perform_authentication(request) 身份校验
#2.check_permissions(request) 权限校验
#3.check_throttles(request) 访问频率校验
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)
drf的Request类
-data(post提交的数据,json格式,urlencoded,fromdata编码方式的数据)
-data的类型并不是固定的,可能是QueryDict,也可能是字典
-query_params—>原生的GET
-重写了__getattr__ 对象.属性 当属性不存在就会执行该方法
return getattr(self._requset,‘属性’)