DRF之解析器组件

解析器组件

Django 原生解析器

  1. from django.core.handlers.wsgi import WSGIRequest
  2. POST = property(_get_post, _set_post), 找 def _load_post_and_files(self)函数,判断类型,然后进行解析封装。只支持 content_type == ‘multipart/from-data’ 。也可以进行自定义封装,但是遵循开放封闭原则,不要更改源代码。
class LoginView(View):

    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        print(request.POST)
        origin_data = request.body
        parsed_data = origin_data.decode('utf-8')
        print(parsed_data)
        return HttpResponse("ok")

DRF的解析器

from rest_framework.views import APIView
from rest_framework.parsers import FormParser


class LoginView(APIView):
    parser_classes = [FormParser]
    # 此时加了固定的解析器,就只能解析formdata了

    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        # print(request.POST)
        # origin_data = request.body
        # parsed_data = origin_data.decode('utf-8')
        # print(parsed_data)
        print(request.data)
        # request.data 是一个函数,一个 porperty 装饰的方法
        return HttpResponse("ok")
  1. views.LoginView.as_view()
  2. LoginView 里面没有 as_view 方法,到父类 APIView 去找
  3. 执行 View 里面得 as_view() 方法,返回函数
def view(request, *args, **kwargs):
 self = cls(**initkwargs)
    if hasattr(self, 'get') and not hasattr(self, 'head'):
        self.head = self.get
    self.request = request
    self.args = args
    self.kwargs = kwargs
    return self.dispatch()
  1. url 和视图函数之间得绑定关系建立完毕 {"login": view}, 等待用户请求
  2. 接受到用户请i去:login,到建立好的绑定关系里面执行对应得视图函数:view(request)
  3. 视图函数的执行结构是什么就返回给用户什么:self.dispatch(),self.diaptch() 的执行结果是什么,就返回给用户是什么
  4. 此时的 self 代表的就是 LoginView 对象
  5. 开始找 dispatch 方法,self里面没有,LoginView里面没有,在APIView里面有
  6. 开始执行 APIView 里面的 dispatch
  7. 最后找到 http 方法(GET,POST,PUT,DELETE)
  8. 开始执行找到的方法(GET),self.get(), self此时代表LoginView的实例化对象
11.1 假设接收到的是POST请求, 执行request.data
11.2 根据分析,所有的解析工作都在request.data里面实现,且data是一个方法(被装饰后的)
11.2 开始执行request.data
	@property
	def data(self):
		if not _hasattr(self, '_full_data'):
			self._load_data_and_files()
		return self._full_data
11.3 执行self._load_data_and_files
11.4 执行self._data, self._files = self._parse()
11.5 parser = self.negotiator.select_parser(self, self.parsers)
	11.5.1 开始找self.parsers
	11.5.2 self.get_parses()
			[ parse() for parse in self.parser_classes ]
		11.5.3 parser_classes = api_settings.DEFAULT_PARSER_CLASSES
		11.5.4 from rest_framework import api_settings
		11.5.5 api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
	11.5.6 class APISettings():pass
	11.5.7 找不到DEFAULT_PARSER_CLASSES,__getattr__
		'DEFAULT_PARSER_CLASSES': (
		'rest_framework.parsers.JSONParser',
		'rest_framework.parsers.FormParser',
		'rest_framework.parsers.MultiPartParser'
	),
	11.5.8 首先找程序的settings
	11.5.9 然后找rest_framework的settings

11.6 self._data就是我们想要的数据
11.7 DRF将self._data = data
11.8 request.data

DRF的所有功能都是在as_view() 和 dispatch里面重写的

而解析器组件在 dispatch 方法里面重写了,具体是在重新封装的Request对象里面

#  源码
class LoginView(APIView):
	def get(self, request):
	    pass
		
	def post(self, request):
		request.data  # 新的request对象 @property
		return


class APIView(View):
	@classmethod
	def as_view(cls, **initkwargs):
	    pass
		super(APIView, cls).as_view(**initkwargs)
		
	def initialize_request(self, request, *args, **kwargs):
	
		from rest_framework.request import Request

		return Request(
			request,  # 原生request对象
			parsers=self.get_parsers(), #
			authenticators=self.get_authenticators(),
			negotiator=self.get_content_negotiator(),
			parser_context=parser_context
		)
			
	def dispatch(self):
	    pass
		request = self.initialize_request(request, *args, **kwargs)
        self.request = request
		
	def get_parsers(self):
	
		return [parser() for parser in self.parser_classes]

你可能感兴趣的:(Django,框架)