一. 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
dispatch
    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)
initial

相关文章:

  • 2021-05-31
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-07
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-11-20
  • 2021-10-09
  • 2019-09-28
  • 2022-03-07
  • 2022-12-23
相关资源
相似解决方案