drf的基本使用、APIView源码分析和CBV源码拓展

cbv源码拓展

扩展,如果我在Book视图类中重写dispatch方法
	-可以实现,在get,post方法执行之前或者之后执行代码,完成类似装饰器的效果
       def dispatch(self, request, *args, **kwargs):
            # 请求执行前代码
            response=super().dispatch(request, *args, **kwargs)
            # 请求执行后代码
            return response
        
        # 这样你的get、post...请求来的时候和结束后就会执行自定义的代码

DRF基本使用及执行流程分析(3星)

基本使用

在views.py中

from rest_framework.views import APIView  # 继承这个类
from rest_framework.response import Response  # 这个是drf封装的


class BookAPIView(APIView):
    def get(self, request, *args, **kwargs):
        return Response('get请求')

    def post(self, request, *args, **kwargs):
        return Response('post请求')

在urls.py中

from app01 import views

urlpatterns = [
    path('book/', views.BookAPIView.as_view())
]

image

APIView执行流程(源码分析)

0. APIView继承了django的View

1. APIView中重写了as_view
    @classmethod
    def as_view(cls, **initkwargs):
        # 调用父类的as_view
        view = super().as_view(**initkwargs)
        # 只要继承APIView以后所有的视图都没有csrf保护了,不管是否注释掉中间件 
        return csrf_exempt(view)
    
2 再执行self.dispatch()---->APIView的dispatch
    def dispatch(self, request, *args, **kwargs):
		# 包装了一个新的request对象,基于原来的request对象包装你的
        # 这个request对象是新的request对象,是drf提供的Request类的对象
        # 新的request包含,原来老的request(django的request)
        # self._request = request(老)
        request = self.initialize_request(request, *args, **kwargs)
        #print(request._request)  老的request对象
        try:
        	# 认证,权限,频率。。。
            self.initial(request, *args, **kwargs)
            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
            #视图类中get或其他请求方法的执行
            response = handler(request, *args, **kwargs)
        except Exception as exc:
            # 如果在视图类中有错误,会被捕获(全局异常处理)
            response = self.handle_exception(exc)
        #把response包装了一下,返回了
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

image

image

image

image

image

image

image

image

image

image

3 在视图类中使用的request对象是新的request对象,老的是request._request
	-新的request.GET拿到的还是老的GET,原理如下(Request类重写了__getattr__)
       def __getattr__(self, attr):
            try:
                return getattr(self._request, attr)
            except AttributeError:
                return self.__getattribute__(attr)
            
4 结论:以后继承了APIView后,request对象成了新的,但是跟原来一样用

5 新的request对象中有一个属性  data
	-data是post请求携带的数据----》字典
    -无论是什么编码格式,只要是post提交的数据,都在request.data中
	-以后再取值,都从request.data中取

image

image

总结

以后如果使用了drf, 继承了APIView(drf提供了很多view, 他们都是继承了APIView), 执行流程如下:

1.包装了一个新的request,在视图函数中使用时,跟原来没有区别

2.POST请求在request.data中取

3.GET请求在request.query_params中取

Request类(drf的)中需要掌握的

  1. request.data 方法包装成了数据属性
  2. request.query_params 就是request._request.GET
  3. request.FIELS 还是取上传的文件

APIView类

  1. 包装了新的request
  2. 执行了认证,权限,频率...
  3. 处理了全局异常
  4. 包装了response对象
posted @ 2022-03-30 21:14  zong涵  阅读(96)  评论(0编辑  收藏  举报