一. REST framework的请求生命周期
基于rest-framework的请求处理,与常规的url配置不同,通常一个django的url请求对应一个视图函数,在使用rest-framework时,我们要基于视图对象,然后调用视图对象的as_view函数,as_view函数中会调用rest_framework/views.py中的dispatch函数,这个函数会根据request请求方法,去调用我们在view对象中定义的对应的方法,就像这样:
from app01 import views as app01_view urlpatterns = [ url(r'^limits/', api_view.LimitView.as_view()), ]
二. 实例代码
1. 代码
from rest_framework.views import APIView from rest_framework import exceptions from rest_framework.response import Response from rest_framework.throttling import SimpleRateThrottle class MySimpleRateThrottle(SimpleRateThrottle): scope = "limit" def get_cache_key(self, request, view): return self.get_ident(request) class LimitView(APIView): authentication_classes = [] permission_classes = [] throttle_classes = [MySimpleRateThrottle, ] # 自定义分流类 def get(self, request, *args, **kwargs): self.dispatch return Response('控制访问频率示例') def throttled(self, request, wait): class MyThrottled(exceptions.Throttled): default_detail = '请求被限制.' extra_detail_singular = 'Expected available in {wait} second.' extra_detail_plural = '还需要再等待{wait}' raise MyThrottled(wait)
2. 执行流程
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 # 1. 对request进行加工 # request封装了 """ request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context """ request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? try: # 初始化request # 确定request版本,用户认证,权限控制,用户访问频率限制 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) # 6. 二次加工request self.response = self.finalize_response(request, response, *args, **kwargs) return self.response
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. # 2. 确定request版本信息 version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted # 3. 用户认证 self.perform_authentication(request) # 4. 权限控制 self.check_permissions(request) # 5. 用户访问频率限制 self.check_throttles(request)