Django-rest-framework Request请求与Response响应
一、请求Request
REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象。
1.对象路径
from rest_framework.request import Request
分析源码:
from rest_framework.request import Request
class Request:
    def __init__(self, request, parsers=None, authenticators=None,
                 negotiator=None, parser_context=None):
        # 二次封装request,将原生request作为drf中request对象的 _request 属性
        self._request = request
    def __getattr__(self, item):
        return getattr(self._request, item)
    # 请求对象: request.data  前端以三种编码方式传入的数据,都可以取出来
    # 请求对象: request.query_params与Django标准的request.GET相同,只是更换了更正确的名称而已。
2.常用属性
- 
request.data:返回解析之后的请求体数据,类似于Django中标准的request.POST和request.FILES属性,但提供如下特性:data 特征
- 包含了解析之后的文件和非文件数据
 - 包含了对
POST、PUT、PATCH请求方式解析后的数据 - 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
 
 - 
request..query_params:与Django标准的request.GET相同,只是更换了更正确的名称而已。 
3.配置能够解析的请求编码格式 : parser_classes
全局配置
- 在 
settings.py文件中配置如下: 
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser'
    ]
}
只能够解析三种请求编码格式:
JSON、FormDate、urlencoded
局部配置
- 在单独某个视图类中配置:
 
parser_classes = [FormParser]
配置该项, 视图类首先是先查找自己类中是否有该配置
二、响应Response
1.对象路径
from rest_framework.response import Response
源码分析
from rest_framework.response import Response
class Response:
    def __init__(self, data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None):
        """
        :param data:    你要返回的数据,字典
        :param status:  返回的状态码,默认是200,
            from rest_framework import status  # 在这个路径下, 它把所有使用到的状态码都定义成了常量
        :param template_name: 渲染的模板名字(自定制模板),不需要了解
        :param headers:  响应头,可以往响应头放东西,就是一个字典
        :param content_type:  响应的编码格式,application/json 和 text/html
        """
2.常用属性
data:为响应准备的序列化处理后的数据(字典)headers: 用于存放响应头信息的字典status: 状态码, 默认200 (http请求的状态码)template_name: 模板名称, 如果使用HTMLRenderer 时需指明content_type: 响应数据的Content-Type, 通常此参数无需传递, REST framework会根据前端所需类型数据来设置该参数
三、配置响应格式
1.两种显示格式
- 我们使用浏览器访问 DRF 时, 返回的是一个页面
 
- 如果使用 Postman 这样的软件访问, 那么展示的就是 JSON 格式, ajax 请求也是 JSON格式
 
2.配置响应格式 : renderer_classes
配置的加载执行顺序
- 先从自己类中找——》项目的setting中找——》默认配置文件中找
 
全局配置
- 在settings.py文件中进行配置
 
# 在 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,]
四、状态码
为了方便设置状态码,REST framewrok在rest_framework.status模块中提供了常用状态码常量。
导入status模块
from rest_framework import status
# "status." 点可取状态码
# 默认响应状态码 : 200
1xx:信息告知
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS
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
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
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
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()),
3.自定义Response类(最终版)
- json_response.py文件(方便以后copy)
 
# -*- coding:utf-8 -*-
"""
常用的Response以及Django的Response、DRF的Response
"""
import six
from rest_framework.response import Response
from rest_framework.serializers import Serializer
from rest_framework.status import HTTP_200_OK
from django.http.response import DjangoJSONEncoder, JsonResponse
class OpDRFJSONEncoder(DjangoJSONEncoder):
    """
    重写DjangoJSONEncoder
    (1)默认返回支持中文格式的json字符串
    """
    def __init__(self, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False,
                 indent=None, separators=None, default=None):
        super().__init__(skipkeys=skipkeys, ensure_ascii=False, check_circular=check_circular,
                         allow_nan=allow_nan, sort_keys=sort_keys, indent=indent, separators=separators,
                         default=default)
class SuccessResponse(Response):
    """
    标准响应成功的返回, SuccessResponse(data)或者SuccessResponse(data=data)
    (1)默认错误码返回200, 不支持指定其他返回码
    """
    def __init__(self, data=None, msg='success', status=None, template_name=None, headers=None, exception=False,
                 content_type=None):
        self.std_data = {
            "code": 200,
            "data": data,
            "msg": msg,
            "status": 'success'
        }
        super().__init__(self.std_data, status, template_name, headers, exception, content_type)
    def __str__(self):
        return str(self.std_data)
class ErrorResponse(Response):
    """
    标准响应错误的返回,ErrorResponse(msg='xxx')
    (1)默认错误码返回201, 也可以指定其他返回码:ErrorResponse(code=xxx)
    """
    def __init__(self, data=None, msg='error', code=201, status=None, template_name=None, headers=None,
                 exception=False, content_type=None):
        self.std_data = {
            "code": code,
            "data": data,
            "msg": msg,
            "status": 'error'
        }
        super().__init__(self.std_data, status, template_name, headers, exception, content_type)
    def __str__(self):
        return str(self.std_data)
class ErrorJsonResponse(JsonResponse):
    """
    标准JsonResponse, 仅ErrorResponse无法使用时才能使用ErrorJsonResponse
    (1)默认错误码返回2001, 也可以指定其他返回码:ErrorJsonResponse(code=xxx)
    """
    def __init__(self, data, msg='error', code=201, encoder=OpDRFJSONEncoder, safe=True, json_dumps_params=None,
                 **kwargs):
        std_data = {
            "code": code,
            "data": data,
            "msg": msg,
            "status": 'error'
        }
        super().__init__(std_data, encoder, safe, json_dumps_params, **kwargs)
class SuccessJsonResponse(JsonResponse):
    """
    标准JsonResponse, SuccessJsonResponse(data)SuccessJsonResponse(data=data)
    (1)仅SuccessResponse无法使用时才能推荐使用SuccessJsonResponse
    """
    def __init__(self, data, msg='success', encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs):
        std_data = {
            "code": 200,
            "data": data,
            "msg": msg,
            "status": 'success'
        }
        super().__init__(std_data, encoder, safe, json_dumps_params, **kwargs)
                版权声明:
                                    
作者:淘小欣                                    
链接:https://blog.taoxiaoxin.club/175.html
                                    
来源:淘小欣的博客                                    
文章版权归作者所有,未经允许请勿转载。
                                
                        THE END
                    
                    
                    0
        
                        二维码        
                
                        海报        
        
            
            Django-rest-framework Request请求与Response响应
            
                一、请求Request
REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象……            
            
                

共有 0 条评论