28 drf 请求与响应

892次阅读
没有评论

共计 4508 个字符,预计需要花费 12 分钟才能阅读完成。

一. 请求 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 时, 返回的是一个页面

28 drf 请求与响应

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

28 drf 请求与响应

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 下去找

正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计4508字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)