zoukankan      html  css  js  c++  java
  • 🍖drf 请求与响应

    一.请求 Request

    REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象

    0.对象路径

    from rest_framework.request import Request
    

    1.常用属性

    • request.data : 存放的是原来 request.body 中的所有数据, (前端传过来的三种格式的数据)
    # data 特征
    - 包含了解析之后的文件和非文件数据
    - 包含了对POST、PUT、PATCH请求方式解析后的数据
    - 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
    
    • request.query_params : 与Django标准的request.GET相同,只是更换了更正确的名称而已, 也可以直接使用 request.GET

    2.配置能够解析的请求编码格式 : parser_classes

    • 全局配置
    # 在 settings.py 文件中配置
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        ]
    }
    

    只能解析这三种请求编码格式 : urlencoded, formdata, json

    • 局部配置
    # 在某个视图类中配置
    parser_classes = [FormParser]
    

    配置该项, 视图类首先是先查找自己类中是否有该配置

    二.响应 Response

    0.对象路径

    from rest_framework.response import Response
    

    1.常用属性

    • data : 为响应准备的序列化处理后的数据(字典)

    • headers : 用于存放响应头信息的字典

    • status : 状态码, 默认200 (http请求的状态码)

    • template_name : 模板名称, 如果使用HTMLRenderer 时需指明

    • content_type : 响应数据的Content-Type, 通常此参数无需传递, REST framework会根据前端所需类型数据来设置该参数

    三.配置响应格式

    1.两种显示格式

    • 我们使用浏览器访问 DRF 时, 返回的是一个页面

    image-20210416210018964

    • 如果使用 Postman 这样的软件访问, 那么展示的就是 JSON 格式, ajax 请求也是 JSON格式

    image-20210416210520119

    2.配置响应格式 : renderer_classes

    • 全局配置
    # 在 settings.py 文件中进行配置
    REST_FRAMEWORK = {
        'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
            'rest_framework.renderers.JSONRenderer',  # json渲染器
             'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
        )
    }
    
    • 局部配置
    # 在某个视图类中进行配置
    from rest_framework.renderers import JSONRenderer
    renderer_classes=[JSONRenderer,]
    
    • 配置查找顺序
    配置的加载执行顺序: 先从自己类中找 -> 项目的setting中找 -> 默认配置文件中找
    

    四.状态码

    为了方便设置状态码,REST framewrok自己提供了许多常用状态码, 并将其都做成了常量

    0.导入 status 模块

    from rest_framework import status
    # "status." 点可取状态码
    # 默认响应状态码 : 200
    

    1.1xx : 信息告知

    HTTP_100_CONTINUE
    HTTP_101_SWITCHING_PROTOCOLS
    

    2.2xx : 成功

    HTTP_200_OK
    HTTP_201_CREATED
    HTTP_202_ACCEPTED
    HTTP_203_NON_AUTHORITATIVE_INFORMATION
    HTTP_204_NO_CONTENT
    HTTP_205_RESET_CONTENT
    HTTP_206_PARTIAL_CONTENT
    HTTP_207_MULTI_STATUS
    

    3.3xx : 重定向

    HTTP_300_MULTIPLE_CHOICES
    HTTP_301_MOVED_PERMANENTLY
    HTTP_302_FOUND
    HTTP_303_SEE_OTHER
    HTTP_304_NOT_MODIFIED
    HTTP_305_USE_PROXY
    HTTP_306_RESERVED
    HTTP_307_TEMPORARY_REDIRECT
    

    4.4xx : 客户端错误

    HTTP_400_BAD_REQUEST
    HTTP_401_UNAUTHORIZED
    HTTP_402_PAYMENT_REQUIRED
    HTTP_403_FORBIDDEN
    HTTP_404_NOT_FOUND
    HTTP_405_METHOD_NOT_ALLOWED
    HTTP_406_NOT_ACCEPTABLE
    HTTP_407_PROXY_AUTHENTICATION_REQUIRED
    HTTP_408_REQUEST_TIMEOUT
    HTTP_409_CONFLICT
    HTTP_410_GONE
    HTTP_411_LENGTH_REQUIRED
    HTTP_412_PRECONDITION_FAILED
    HTTP_413_REQUEST_ENTITY_TOO_LARGE
    HTTP_414_REQUEST_URI_TOO_LONG
    HTTP_415_UNSUPPORTED_MEDIA_TYPE
    HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
    HTTP_417_EXPECTATION_FAILED
    HTTP_422_UNPROCESSABLE_ENTITY
    HTTP_423_LOCKED
    HTTP_424_FAILED_DEPENDENCY
    HTTP_428_PRECONDITION_REQUIRED
    HTTP_429_TOO_MANY_REQUESTS
    HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
    HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
    

    5.5xx : 服务端错误

    HTTP_500_INTERNAL_SERVER_ERROR
    HTTP_501_NOT_IMPLEMENTED
    HTTP_502_BAD_GATEWAY
    HTTP_503_SERVICE_UNAVAILABLE
    HTTP_504_GATEWAY_TIMEOUT
    HTTP_505_HTTP_VERSION_NOT_SUPPORTED
    HTTP_507_INSUFFICIENT_STORAGE
    HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
    

    五.封装自己的Response对象

    1.无自定义, 手动构建

    • views.py
    class Test1(APIView):
        def get(self,request):
            response = {'status':200,'msg':None}
            # 写一堆逻辑,下面伪代码
            res = 1
            if res:
                response['msg'] = '成功'
                response['data'] = {'name':'shawn','age':99}
            else:
                response['status'] = 201
                response['msg'] = '失败'
            return Response(response)
    
    • urls.py
    path('test1/', views.Test1.as_view()),
    

    2.自定义Response类 (初始版)

    • myresponse.py 文件 (自行创建)
    class MyResponse():
        def __init__(self):
            self.status = 200
            self.msg = None
    
        @property
        def get_dict(self):
            return self.__dict__
    
    • views.py
    from mydrf.myresponse import MyResponse
    
    class Test2(APIView):
        def get(self,request):
            # 先实例化得到响应对象
            response = MyResponse()
            # 写一堆逻辑,下面伪代码
            res = 1
            if not res:
                # 直接以的.点方式设置属性
                response.status = 201
                response.msg = '失败了'
            # 返回响应字典
            response.msg = '成功了'
            return Response(response.get_dict)
    
    • urls.py
    path('test2/', views.Test2.as_view()),
    

    3.自定义Response类 (高级版)

    • myresponse.py 文件
    from rest_framework.response import Response
    
    class APIResponse(Response):
        # 继承 Response 类,并将其内的参数全部拿过来,然后添加自定义的参数(属性)
        # 设置一个kwargs接收其余关键字参数
        def __init__(self, code=200, msg=None, data=None, status=None,
                     template_name=None, headers=None,
                     exception=False, content_type=None, **kwargs):
            dic = {'static': code, 'msg': msg}
            if data:
                dic['data'] = data  # 将data数据放在"data"键中
            if kwargs:
                dic.update(kwargs)  # 将kwargs接收的位置参数更新入dic中
            # 调用父类的__init__方法进行初始化
            super().__init__(data=dic, status=status,
                             template_name=template_name, headers=headers,
                             exception=exception, content_type=content_type)
    
    • view.py
    from mydrf.myresponse import APIResponse
    
    class Test3(APIView):
        def get(self, request):
            # 写一堆逻辑,下面伪代码
            res = 1
            if res:
                return APIResponse(msg='成功!', data={'name': 'shawn'}, next='/index/')
            return APIResponse(status=201, msg='失败', next='/login/')
    
    • urls.py
    path('test3/', views.Test3.as_view()),
    

    六.补充

    Django 中的 templates 文件夹下的模板文件, 在查询的时候优先会到项目的 templates 文件夹下去找, 找不到再去相应的 APP 下去找, 找不打就报错, 不会跑到其他的 APP 下去找

  • 相关阅读:
    慕课网-安卓工程师初养成-3-2 Java中的算术运算符
    慕课网-安卓工程师初养成-3-1 什么是运算符
    慕课网-安卓工程师初养成-2-13 练习题
    慕课网-安卓工程师初养成-2-12 如何在Java中使用注释
    慕课网-安卓工程师初养成-2-11 Java常量
    慕课网-安卓工程师初养成-2-10 Java中的强制类型转换
    试把一个正整数n拆分为若干个
    求解两个给定正整数m、n的最大公约数(m、n)
    统计n!尾部零
    横竖折对称方阵
  • 原文地址:https://www.cnblogs.com/songhaixing/p/14670489.html
Copyright © 2011-2022 走看看