zoukankan      html  css  js  c++  java
  • 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,方便读源码
  • 相关阅读:
    Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array -- 逆向思维
    一种压缩图片的方法---Machine learning 之 K-Means
    【Codeforces】Codeforces Round #374 (Div. 2) -- C. Journey (DP)
    strcpy自实现
    Coursera公开课-Machine_learing:编程作业6
    【Codeforces】Codeforces Round #373 (Div. 2) -C
    【Codeforces】Codeforces Round #373 (Div. 2)
    【Leetcode】376. Wiggle Subsequence
    Coursera公开课-Machine_learing:编程作业5
    C++实现日期类(Date类)
  • 原文地址:https://www.cnblogs.com/pdun/p/10872763.html
Copyright © 2011-2022 走看看