• drf总流程


    rest_framework 总流程

    class APIView(View):
    
    # 配置文件
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
    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
    
    settings = api_settings
    
    schema = DefaultSchema()
    
    
    
    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.
    	"""
    	
    	# 1,封装args,和kwargs
    	self.args = args
    	self.kwargs = kwargs
    	
    	# 2,封装新的request,执行self.initialize_request(request, *args, **kwargs)函数,见下面62行
    	request = self.initialize_request(request, *args, **kwargs)
    	self.request = request
    	
    	
    	# 4,封装请求头
    	self.headers = self.default_response_headers  # deprecate?
    	# self.headers = {'Allow': 'POST, OPTIONS', 'Vary': 'Accept'}
    
    
    	try:
    		# 5,执行initial 方法,详见下面78行
    		self.initial(request, *args, **kwargs)
    		
    			
    		# 6,获取请求方式
    		# Get the appropriate handler method,
    		# http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] 
    		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
    		
    		
    		# 6,处理请求方式,会首先会找自己定义的self 的['get', 'post', 'put', 'patch', 'delete']
    		  自己没有就基类View的['get', 'post', 'put', 'patch', 'delete']方法
    		response = handler(request, *args, **kwargs)
    
    	except Exception as exc:
    		response = self.handle_exception(exc)
    		
    		
    	# 8,返回最终的response对象
    	self.response = self.finalize_response(request, response, *args, **kwargs)
    	return self.response
    	
    	
    	
    # 3,封装request,新的Request返回值返回给步骤2
    def initialize_request(self, request, *args, **kwargs):
    	"""
    	Returns the initial request object.
    	"""
    	parser_context = self.get_parser_context(request)
    
    	return Request(
    		request,
    		
    		# 3.1 封装解析器
    		parsers=self.get_parsers(),
    		
    		# 3.2 封装auth实例化对象列表
    		authenticators=self.get_authenticators(),
    		
    		# 3.3,封装实例化对象列表
    		negotiator=self.get_content_negotiator(),
    		parser_context=parser_context
    	)
    	
    	
    # 5,执行initial方法,这是整个drf的核心组件,
    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
    
    
    
    	# 5.1,版本信息
    	# Determine the API version, if versioning is in use.
    	version, scheme = self.determine_version(request, *args, **kwargs)
    	request.version, request.versioning_scheme = version, scheme
    
    	
    	
    	# 5.2 用户认证
    	# Ensure that the incoming request is permitted
    	self.perform_authentication(request)
    	
    	
    	# 5.3 权限认证
    	self.check_permissions(request)
    	
    	
    	# 5.4 限流机制
    	self.check_throttles(request)
    

    配置文件

    REST_FRAMEWORK = {
    # 分页
    "PAGE_SIZE": 2,
    "DEFAULT_PAGINATION_CLASS": 'rest_framework.pagination.PageNumberPagination',
    
    # 版本
    "DEFAULT_VERSIONING_CLASS": 'rest_framework.versioning.URLPathVersioning',
    "ALLOWED_VERSIONS": ['v1', 'v2'],
    "VERSION_PARAM": 'version',
    
    # 匿名用户的request.user ,request.token
    #"UNAUTHENTICATED_USER": None,
    #"UNAUTHENTICATED_TOKEN": None,
    
    # 限流
    "DEFAULT_THROTTLE_CLASSES": ['rest_framework.throttling.AnonRateThrottle',
                                 'rest_framework.throttling.UserRateThrottle'],
    "DEFAULT_THROTTLE_RATES": {"anon": '3/m',
                               "user": '3/m'},
    
    # jwt auth认证
    "DEFAULT_AUTHENTICATION_CLASSES": ['myviews.extensions.auth.TokenAuthentication'],}
    
    # jwt-token期限
    JWT_AUTH = {'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
                'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),}
    希望你眼眸有星辰,心中有山海,从此以梦为马,不负韶华
  • 相关阅读:
    Visual Studio的多语言加载项 Multi-Language for Visual Studio
    C#(99):文件监视 FileSystemWatcher
    亿图Edraw Project,甘特图
    C#(99):格式化信息、格式化数字、格式化日期
    小程序访问接口由于缺少中间证书访问失败的问题
    微信授权登录“redirect_uri域名与后台配置不一致”,公众号错误码10003
    如何在idea上新建一个springboot项目
    CSS实现网页背景图片自适应全屏的方法
    Umi与Keycloak整合
    Canal帮助MySQL进行数据同步
  • 原文地址:https://www.cnblogs.com/daviddd/p/11918405.html
Copyright © 2020-2023  润新知