zoukankan      html  css  js  c++  java
  • Django框架(十八)—— CBV源码分析、restful规范、restframework框架

    CBV源码分析、restful规范、restframework框架

    一、CBV源码分析

    1、url层的使用CBV

    from app01 import views
    
    url(r'book/',views.Book.as_view)
    

    2、as_view方法

    as_view是一个类方法,实际上是一个闭包函数(内层函数包含对外层作用域的使用)

    请求来了以后,调用as_view方法,调用函数中的view方法,view方法是调用了dispatch方法

    @classonlymethod
        def as_view(cls, **initkwargs):
            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
                # 如果调用的类Book没有写dispatch方法,就会调用View中的dispatch方法
                return self.dispatch(request, *args, **kwargs)
            view.view_class = cls
            view.view_initkwargs = initkwargs
    
            return view
    

    3、view方法

    view 方法是一个闭包函数,最终调用了 dispatch 方法
    

    4、dispatch方法(可以在视图层的CBV中重写)

    getattr(self, 'get'[,default])   # 获取对象的get属性的内存地址,如果没有get,返回默认值
    setattr(self, 'get', 'get__all')  # 相当于将get的内存地址设置为get__all 的内存地址
    hasattr(self,'get')     # 判断对象是否有get 属性
    

    dispatch方法相当于是根据不同的请求方式,分发到对应的函数属性中

    def dispatch(self, request, *args, **kwargs):
    	# http_method_names -->  ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        if request.method.lower() in self.http_method_names:
            # 这里的self.http_method_not_allowed 是默认值,如果没有改method,获取其地址
            # 如果是get请求,那么handler就是get;若是post请求,handler相当于post
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
    

    5、views层的CBV

    class Books(View):
        # 获取所有图书
        def get(self, request):
            print(type(request))
            response = {'status': 100, 'data': None}
            books = models.Book.objects.all()
            # 先构造出所有书籍的字典的列表
            ll = [{'name': book.name, 'price': book.price} for book in books]
            # 返回数据是json格式数据
            response['data'] = ll
            # safe = True 表示数据可以是列表
            return JsonResponse(response, safe=False)
     
    

    6、CBV执行过程总结

    请求 --> 调用View中的as_view --> 调用as_view中的闭包view --> view中会实例化产生一个对象 --> 调用对象的dispatch --> 没有,去类中找dispatch --> 没有dispatch --> 去View中找,找到dispatch,执行 --> 分发到不同的函数,执行并返回
    

    二、restful规范

    resful规范的接口,用fbv和cbv都可以,自定义方法,CBV中重写,FBV中利用装饰器

    1、什么是restful

    • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
    • 面向资源编程,网络中的所有的数据都是资源

    2、10条规范

    (1)https协议

    API与用户的通信协议,总是使用 HTTPs协议 ------ https比http安全

    (2)域名

    https://api.example.com    ----- 尽量将API部署在专用域名(会存在跨域问题)
    https://127.0.0.1/api/   ----- 简单,推荐使用
    

    (3)版本

    每个接口都应有版本

    https://example/api/v2   ----- v2 版本
    

    (4)路径

    视网络上任何东西都是资源,均使用名词表示(可复数)

    https://example/api/v1/zoos
    
    https://example/api/v1/animals
    
    https://example/api/v1/employees
    

    (5)method

    • GET :从服务器取出资源(一项或多项)
    • POST :在服务器新建一个资源
    • PUT :在服务器更新资源(客户端提供改变后的完整资源)
    • PATCH :在服务器更新资源(客户端提供改变的属性)
    • DELETE :从服务器删除资源

    (6)过滤

    通过在url上传参的形式传递搜索条件

    https://example/api/v1/zoos?limit=10
    
    https://example/api/v1/animals?offset=20
    
    https://example/api/v1/employees?name=tom
    

    (7)状态码

    请求回去,需要有状态码

    200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
    201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
    202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
    204 NO CONTENT - [DELETE]:用户删除数据成功。
    400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
    401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
    403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
    404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
    406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
    410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
    422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
    500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
    

    (8)错误处理

    应返回错误信息,error当做key

    {status:100,error:'错误信息写上'}
    

    (9)返回结果

    针对不同操作,服务器向用户返回的结果应该符合以下规范

    GET /collection:返回资源对象的列表(数组)
    GET /collection/resource:返回单个资源对象
    POST /collection:返回新生成的资源对象
    PUT /collection/resource:返回完整的资源对象
    PATCH /collection/resource:返回完整的资源对象
    DELETE /collection/resource:返回一个空文档
    

    (10)返回结果中提供链接(Hypermedia)

    Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API 方法,使得用户不查文档,也知道下一步应该做什么

    {
        status:100
        msg:成功
        url:127.0.0.1/books/1
    }
    

    三、drf(Django restframework)框架

    1、什么是drf

    它是一个app,只是用来快速的构建restful规范的接口

    2、drf的使用

    一定要在settings中注册 INSTALLED_APPS=[rest_framework]

    from rest_framework.views import APIView
    
    class Books(APIView):
        # 现在这个request对象,已经不是原来django中的request对象了,它是rest_framework.request下的Request
        def put(self, request, pk):
            # django.core.handlers.wsgi.WSGIRequest----原来的djagno中的request的类
            # 现在的request已经成了:rest_framework.request.Request
            # 以后再取数据,直接从request.data中取
            print(request.data)
            # 前端传过来的编码格式:json格式:{'name': '水都是', 'price': '15'}
            #  前端传过来的编码格式:urlencoded格式:<QueryDict: {'name': ['红楼梦'], 'price': ['15']}>
            # request.data是谁的对象?
            # request.data不同编码格式过来,它可能是不同类的对象,但是用法是一样的
    
            # 原来的request是:request._request
            print(type(request._request))
    
            print(request._request.GET)
            # 也能取出来(method,GET,POST,BODY)
            print(request.GET)
    
            return JsonResponse({'status': 100, 'msg': '修改成功'})
    

    注意点

    • request.data 是个方法,通过property装饰器包装成了属性,前台传过来body体中数据的数据,放在里面
      • 前端传过来的编码格式:json格式:{'name': '水都是', 'price': '15'}
      • 前端传过来的编码格式:urlencoded格式:<QueryDict: {'name': ['红楼梦'], 'price': ['15']}>
    • request.query_params 这个是原来GET中的数据
    • request把原来的request包装进去了
    • 一旦继承了APIView类,request就被包装过,不再是Django中那个request,而是rest_framework.request.Request的对象
    • csrf_exempt:局部禁用csrf(csrf是可以局部使用,局部禁用),rest_framework有自身的方法放置csrf攻击,不需要写{% csrf_token %}

    3、rest_framework中CBV执行流程

    请求 --> rest_framework的as_view --> super调用父类View的as_view --> 父类中as_view调用比和函数view,实例化产生一个对象 --> 调用改对象的dispatch --> 自身没有,类中也没有,去父类中APIView中 --> 有dispatch方法 --> 调用rest_framework中的dispatch --> 分发到get、post、put等函数中执行
    
  • 相关阅读:
    Java的学习笔记(二)
    Java的学习笔记
    简单界面生成
    登录界面
    播放器
    java计划
    求和
    修改后的抽奖系统
    第十周作业
    JAVA第五次作业
  • 原文地址:https://www.cnblogs.com/linagcheng/p/10102240.html
Copyright © 2011-2022 走看看