drf

前言

#在CBV中,知道,分发函数的任务是在dispatch,(view中的方法)
#这里APIview继承了view,但其重写了dispatch方法,

一、什么是drf

#drf(django rest framework)框架(django的app)
#安装:
    djangorestframework
#它是一个app,所以需要在settings中注册
  ‘rest_framework’
只是快速的构建resful规范的接口 csrf_exempt:局部禁用csrf(csrf是可以局部使用,局部禁用) #drf可以注释csrf 以后再执行的dispatch方法是APIView的dispatch方法 getattr和setattr #重点掌握这三点: request.data 是个方法,包装成了属性,前台传过来body体中数据的数据,放在里面 request.query_params 这个是原来GET中的数据 request把原来的request包装进去了
from django.views.decorators.csrf import csrf_exempt,csrf_protect

csrf_exempt局部禁用

csrf_protect局部使用
 
from rest_framework.views import APIView
class Books(APIView):
    # 现在这个request对象,已经不是原来django中的request对象了,它是rest_framework.request下的Request
    def put(self, request, pk):

            # 原来的request是:request._request
            print(request._request.GET) #按理说可以这样取值
          
            print(request.GET)  # 为什么这样也能取出来(method,GET,POST,BODY)
        print(request.data)
# 如果前端传过来的编码格式:json格式:{'name': '西游记', 'price': '15'}
#如果前端传过来的编码格式:urlencoded格式:<QueryDict: {'name': ['红楼梦'], 'price': ['15']}>
    # request.data是谁的对象?
    # request.data不同编码格式过来,它可能是不同类的对象,但是用法是一样的
# class Student():
#     name='pdun'
#
#     def __init__(self,age):
#         self.age=age
#
# s1=Student(1)
# print(s1.name)
# print(s1.age)
# print(s1.sex)    #想赋值,只能重写__setattr__方法


class Student():
    name='pdun'

    def __init__(self,age):
        self.age=age

    def __getattr__(self, item):          #通过点取值,会走到这里
        return '没有这个属性'

    def __setattr__(self, key, value):    #通过点赋值,会走到这里
        pass

    def __getitem__(self, item):        #通过中括号取值,会走到这里
        pass

    def __setitem__(self, key, value):    #通过中括号赋值,会走到这里
        pass

s1=Student(1)
s1.sex='man'
print(s1.sex)
分析源码辅助代码
#此时点API进去读源码
class APIView(View):       #继承了View
    @classmethod
    def as_view(cls, **initkwargs):       #重写了as_view的方法
          #执行父类的as_view方法,拿到view的内存地址,
        view = super(APIView, cls).as_view(**initkwargs)
           #把原来的view.cls替换为现在的
        view.cls = cls
        view.initkwargs = initkwargs
    
            #这一步相当于给view添加了一个装饰器,
        return csrf_exempt(view)  #局部禁用csrf  ,相当于给view加了一个装饰器  
#view方法最终执行的是disdispatch,而API中有自己的dispatch

#此时来到APIview中的dispatch方法

    def dispatch(self, request, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs        #简单的赋值


           #此时后边(括号内)request是原来的request,
           #经过initialize_request处理后,不再是request    
  
        request = self.initialize_request(request, *args, **kwargs)
        
        self.request = request      #执行后的赋值
        self.headers = self.default_response_headers  

#此时点initialize_request进去

    def initialize_request(self, request, *args, **kwargs):

        parser_context = self.get_parser_context(request)
         
           #类实例化产生对象,产生这个Request对象,是drf的request
        return Request(
            request,    #原来的request包含在drf的request之内
            # 解析用的
            parsers=self.get_parsers(),
            #认证用的
            authenticators=self.get_authenticators(),
           # 分页用的
            negotiator=self.get_content_negotiator(),
             #解析用
            parser_context=parser_context
        )

#此时点Request进去 (from rest_framework.request import Request点这也可以)
class Request(object):

        self._request = request      #原来的request变成_request
                                                 #所以在外界可以request._request拿到原来的



#这就是为什么_request.GET和request.GET都能取到值的原因
    def __getattr__(self, attr):

        try:

            #通过反射,去原来的request中拿出要取的属性(如:GET,POST...)
            return getattr(self._request, attr)
        except AttributeError:
            return self.__getattribute__(attr)

     #request.query_params  这个是原来GET中的数据
    @property
    def query_params(self):
        return self._request.GET

    #request.data 是个方法,包装成了属性,前台传过来body体中数据的数据,放在里面
    @property
    def data(self):
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
        return self._full_data
源码分析

重点掌握

#request.data 是个方法,包装成了属性,前台传过来body体中数据的数据,放在里面
#request.query_params  这个是原来GET中的数据
#request把原来的request包装进去了  包装成了_request,方便读源码
原文地址:https://www.cnblogs.com/pdun/p/10872763.html