zoukankan      html  css  js  c++  java
  • 第二章 restframework——框架安装与APIView

    第二章 restframework——框架安装与APIView

    一、restframework框架安装

    二、Django的CBV源码分析

    三、APIView介绍

    四、django中的request

    五、restframework中的request 

    一、restframework框架安装

    方式一:pip3 install djangorestframework

    方式二:pycharm图形化界面安装

    方式三:pycharm命令行下安装(装在当前工程所用的解释器下)

    切记去项目settings.py配置中配置restframework

     否则会报如下错误

    二、Django的CBV源码分析

    CBV(class base view):基于类的view,就叫CBV

    Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

    1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
    2. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

    使用步骤:

     ①使用前切记导入View,将创建的类继承自View

     from django.views import View

     ②该类会自动根据post请求与get请求自动分辨请求类型,选择对应的函数def get()或者def post()

     ③dispatch类似装饰器,可以在def get()或者def post()前后添加代码

        记得继承类obj=super().dispatch(request, *args, **kwargs),在其前后添加代码

     ④在路由调用视图函数时记得调用as_view()方法

    from django.views import View
    class AddPublish(View):
        def dispatch(self, request, *args, **kwargs):
            print(request)
            print(args)
            print(kwargs)
            # 可以写类似装饰器的东西,在前后加代码
            obj=super().dispatch(request, *args, **kwargs)
            return obj
    
        def get(self,request):
            return render(request,'index.html')
        def post(self,request):
            request
            return HttpResponse('post')

    源码分析(右击新标签中打开图片可以看的清楚些)

    使用装饰器装饰CBV(dispatch)

    类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。

    Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。

    # 使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,如get,post等做一些操作的时候,这里我们可以手动改写dispatch方法,
    这个dispatch方法就和在FBV上加装饰器的效果一样。
    
    class Login(View):
         
        def dispatch(self, request, *args, **kwargs):
            print('before')
            obj = super(Login,self).dispatch(request, *args, **kwargs)
            print('after')
            return obj
     
        def get(self,request):
            return render(request,'login.html')
     
        def post(self,request):
            print(request.POST.get('user'))
            return HttpResponse('Login.post')

    三、APIView介绍

    使用步骤:

    ①导入模块

    from rest_framework.views import APIView

    ②使CBV继承自restframework中的APIView而非django的View

    上文分析了django中的as_view方法,让我们看看APIView中的as_view()

    @classmethod
        def as_view(cls, **initkwargs):
            """
            Store the original class on the view function.
    
            This allows us to discover information about the view when we do URL
            reverse lookups.  Used for breadcrumb generation.
            """
            if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
                def force_evaluation():
                    raise RuntimeError(
                        'Do not evaluate the `.queryset` attribute directly, '
                        'as the result will be cached and reused between requests. '
                        'Use `.all()` or call `.get_queryset()` instead.'
                    )
                cls.queryset._fetch_all = force_evaluation
    
            view = super(APIView, cls).as_view(**initkwargs)
            view.cls = cls
            view.initkwargs = initkwargs
    
            # Note: session based authentication is explicitly CSRF validated,
            # all other authentication is CSRF exempt.
            return csrf_exempt(view)
    源码as_view()

     

    实际执行的还是djangoView类中的as_view()方法下的view函数

     

    view()执行什么实际就是dispatch执行什么

    然而restframework也重写了dispatch方法(只截取部分)(切记下面的dispatch方法是restframework的,并且该框架核心就在此)

     

    【重要】

    总结:

    views.PublishView.as_view()的执行意味着父类View类型下的as_view()方法下的view(request)的执行,

    由于restframework中dispatch已经重写,view(request)的执行意味着APIView类下的dispatch的执行。

    可能表述不太清晰,具体看下面的流程

    路由as_view()——》【django】View().as_view().view()——》【restframework】dispatch()

    四、django中的request

    在了解django中的request之前先来回顾下http协议的请求数据结构

    如下图get请求中的数据在请求头的url中,而post请求则在请求体内

    下面演示使用Postman

    1.get请求

    ①模拟发起带参数的get请求

    ②页面返回ok

    ③request.GET返回QueryDict对象

     2.django中的POST请求略有不同

    ①模拟发起带参数的post请求(模拟urlencoded发送)

     ②页面返回post

    ③request.POST返回QueryDict对象,body返回body体内容

    ④注意:django的request内的post请求有一个特殊之处,当请求采用json格式时,request.POST没有数据

    源码解析:

     django源码中会有类似如下判断

    # 伪代码
    if
    contentType:urlencoded: a=1&b=2----->{"a":1,"b":2}

    A)通过type查找request的类型

    print(type(request))

    B)导入WSGIRequest

    from django.core.handlers.wsgi import WSGIRequest

    C)点击进入

    D)查看_get_post

    E)查看_load_post_and_files(),印证了上面的猜测

     

    五、restframework中的request

     第三节中分析了restframework中的as_view()实际执行的是restframework自己写的dispatch,那让我们看一下

    initialize_request()

    为了更深入研究,我们看下这个Request类

    也就是说,现在cbv里面的request已经是新的request了,他经过一系列封装,增加了例如解析json格式数据的功能等等

    所以,原生的request方法将不再适用,新的request将拥有新的方法

    ①操作django的request的方法

     

    ②request.data

    【post请求】

    发送json数据

    注意:

    ①django将request的所有方法的数据获取进行了不同的封装,而restframework将request下POST方法(application/json形式)的数据封装成request.data

    ②restframework内的request.POST只能接收urlencoded形式发送的数据

    收到的就是dict类型

    发送urlencoded数据

    收到的依旧是querydict类型

    【get请求】

     

     我们可以尝试request.data能否也取到值(答案是不行),可以证明data对post请求有效

    那再试试操作django的request下的方法

    上面这样写太麻烦了,restframework为我们做了处理

     也可以用request.query_params来取

  • 相关阅读:
    误卸载python2.4导致yum不能用后的修复
    网卡流量查看软件bmon
    DTD约束
    Schema约束
    SAX解析原理示意
    DOM解析原理示意
    XML中文乱码问题
    Web应用的目录结构
    手动+工具开发动态资源
    Tomcat服务器的下载及安装
  • 原文地址:https://www.cnblogs.com/neymargoal/p/9777241.html
Copyright © 2011-2022 走看看