DRF学习之request对象、response对象、parser解析器以及render渲染器类

时间:2024-04-28 22:23:10

一、引入

当类视图不继承Django自带的View类,而继承DRF的APIView类(或其子类)时,APIView会为这个类视图提供如下功能:

  • 继承APIView的视图类具备View的所有特性
  • 提取请求字符串参数的request.query_parms方法
  • 请求体参数的request.data方法
  • APIView为视图类提供了认证,授权,限流等功能

二、Request对象

REST framework 的Request类扩展了标准HttpRequest,增加了对 REST framework 灵活的请求解析和请求身份验证的支持。由于实现原因,Request类不是从HttpRequest类继承,而是使用组合扩展该类。 因此,HttpRequest类的方法和属性依旧是可以使用的。

1、request.query_parms

request.query_params与Django标准的request.GET相同,只是更换了更正确的名称而已。

无论请求方式是什么,URL中的参数,我们在DRF中总是使用request.query_params来获取。例如:

class BookView(APIView):
    def get(request):
        data = request.query_params
        print(data)

        return Response(data)

2、request.data

Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果。这样后端使用统一的方式来获取数据,无论前端传递的是表单,json还是其它格式。后端使用统一的方式接受数据即可。简单来说,无论前端发过来的是xml还是json,请求方式无论是POST还是PUT,都可以直接用request.data直接取一个字典出来。

可以获取到请求体参数,兼容参数格式:

  • application/json: json格式数据
  • x-www-form-urlencoded:表单数据
  • multipart-form-data:html文本等格式数据

可以兼容获取到get,post,put,delete,patch等请求方法的参数

class BookView(APIView):
    def post(request):
        data = request.data
        print(data)

        return Response(data)

三、Response对象

1、响应对象

REST Framework的Response继承自Django的SimpleTemplateResponse类。使用Response类只是为返回内容协商的 Web API 响应提供了一个更好的接口,可以呈现为多种格式。你也可以选择Django的HttpResponse或StreamingHttpResponse,都是可以的。不过DRF官方还是建议我们对继承自APIView类或使用@api_view进行装饰的函数,都返回Response对象。

(1)必须注册app

 INSTALLED_APPS = [
        ...
    	'rest_framework'
	]

(2)Response参数分析

Response(data, status=None, template_name=None, headers=None, content_type=None)
  • data:响应的序列化数据,只能是python内置数据类型(字典,列表,字符串…),否则需要先序列化,在传递。
  • status:响应的状态代码。默认为 200,status包下定义了一堆http状态码常量。
  • headers:在响应中使用的 HTTP 标头字典。
  • template_name:HTMLRenderer选择时使用的模板名称。
  • content_type:指定响应编码格式,一般默认

(3)问题补充

在没有数据迁移的情况下,我们向浏览器发送请求,然后报出了django-session表不存在的情况,该如何解决?

首先这是为什么呢?因为前端访问时带了 sessionid,将请求发送到后端,它就会django-session中取数据,取不到就报错了。

那怎么解决呢?第一种数据迁移生成django-session表;第二种直接去浏览器开发者模式中的应用删除sessionid键值对就可以了

四、请求的parser解析器类

首先我们可以获取到请求体参数,会有三种格式:application/jsonx-www-form-urlencodedmultipart-form-data

而当我们想要只获取json格式的数据该怎么操作,或者只获取可以携带文件的form-data格式又该怎么获取?

DRF中的解析器可以根据请求头中的Content-Type来自动解析参数,使用统一的data属性可以获取到解析后的数据, 默认JSONParser,FormParser,MultiPartParser三个解析器类,正好对应三个数据格式。

1、视图类中局部使用

指定了该视图类使用的解析器为 JSONParser 和 FormParser,用于解析请求数据。

from rest_framework.parsers import JSONParser, FormParser,MultiPartParser
class RequestView(APIView):
    parser_classes = [JSONParser, FormParser]  # 用哪个就写哪个
    def post(self, request):
    publish_ser = PublishSerializer(data=request.data)
        if publish_ser.is_valid():
            publish_ser.save()
            return Response(publish_ser.data)
        else:
            return Response("ERROR")    

2、全局配置文件使用

可以在全局配置文件settings.py中修改DRF全局参数,以REST_FRAMEWORK作为名称

  • pycharm中连续按击2次shilft键,可以全局搜索文件,搜索restframework中的settings.py配置文件并进入

在这里插入图片描述

  • 复制上图画圈的配置文件,将需要的DEFAULT_XXXX_CLASSES复制粘贴至项目的项目全局配置文件settings.py文件中

在这里插入图片描述

  • 不用哪个就注释掉哪个

3、全局配置后,局部再次配置

如果全局配置过后,局部再次配置,会按照局部配置的标准来,由此可知优先级 局部 > 全局

五、响应的render渲染器类

drf 接口会根据客户端类型自动返回不同格式:浏览器返回的结果是html页面,其它返回json格式的数据

如果我们想要统一都返回json格式,该如何操作呢?

DRF中的render渲染器可以根据请求头中的Content-Type来自动渲染前端需要的数据,默认渲染器为JSONRenderer,TemplateHTMLRenderer两个渲染器类。 **如果前端请求头未指定Accept参数或者指定为Accept:application/json,那么会自动返回json格式的数据;如果前端请求头指定Accept参数Accept:text/html,那么会自动返回可浏览的api页面。**与解析类似,它既可以局部配置,也可以全局配置,还可以既全局又局部。

1、视图类中局部配使用

  • renderer_classes一配置,无论是哪种方式请求,返回的也都是json格式的数据
from rest_framework.renderers import JSONRenderer,TemplateHTMLRenderer,BrowsableAPIRenderer
class PublishView(APIView):
    renderer_classes = [JSONRenderer]  # 单独指定渲染器
    def get(self, request):
        publish_qs = models.Publish.objects.all()
        publish_str = PublishSerializer(instance=publish_qs, many=True) 
        return Response(publish_str.data)

2、全局配置文件使用

可以在全局配置文件settings.py中修改DRF全局参数,以REST_FRAMEWORK作为名称

  • pycharm中连续按击2次shilft键,可以全局搜索文件,搜索restframework中的settings.py配置文件并进入

  • 找到DEFAULT_RENDERER_CLASSES,复制到项目的配置文件中来

3、全局配置后,局部再次配置

如果全局配置过后,局部再次配置,会按照局部配置的标准来,由此可知优先级 局部 > 全局

4、补充 TemplateHTMLRenderer,BrowsableAPIRenderer的区别

TemplateHTMLRendererBrowsableAPIRenderer 是 Django REST framework 中常用的两种渲染器,它们在 API 的呈现方式上有一些区别:

  1. TemplateHTMLRenderer

    • TemplateHTMLRenderer 用于将 API 数据呈现为 HTML 页面,通常用于创建支持浏览器访问的 Web API。
    • 当请求中包含 text/html 类型的 Accept 头时,TemplateHTMLRenderer 会将 API 数据渲染为 HTML 格式的页面。
    • 这种渲染器适用于需要在浏览器中直接查看和交互的 API。
  2. BrowsableAPIRenderer

    • BrowsableAPIRenderer 也用于将 API 数据呈现为 HTML 页面,但它提供了更加交互式的浏览器界面,使用户能够通过界面直观地浏览 API 的功能和数据。
    • 当请求中包含 text/html 类型的 Accept 头时,BrowsableAPIRenderer 会呈现一个带有交互式表单和链接的浏览器友好页面,让用户能够进行 API 的测试和浏览。
    • 这种渲染器适用于开发和调试 API 时,提供了方便的界面来查看和测试 API 的功能。

总的来说,TemplateHTMLRenderer 主要用于将 API 数据呈现为普通的 HTML 页面,而 BrowsableAPIRenderer 则提供了一个更加交互式和用户友好的浏览器界面,用于浏览和测试 API。根据具体的需求和使用场景,可以选择合适的渲染器来呈现 API 数据。

六、划重点

1、控制解析格式使用

1)视图类中局部使用
class RequestView(APIView):
    parser_classes = [JSONParser, FormParser]2)全局配置文件使用
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        # 'rest_framework.parsers.JSONParser',
        # 'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser',
    ],
}3)全局配了,局部重新配置
class RequestView(APIView):
    parser_classes = [ FormParser]

2、响应格式使用方式

1)视图类中配置
class RequestView(APIView):
    renderer_classes = [JSONRenderer]2)配置文件中配置
'DEFAULT_RENDERER_CLASSES': [
    'rest_framework.renderers.JSONRenderer',
],3)全局配了,局部再使用
renderer_classes = [JSONRenderer]

3、全局配置文件

REST_FRAMEWORK = {
    # 指定全局渲染引擎
    'DEFAULT_RENDERER_CLASSES': [
        # 此渲染引擎,可以向前端返回json格式数据
        'rest_framework.renderers.JSONRenderer',
        # 此渲染引擎,可以向前端返回可浏览的API页面文档
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
    # 指定全局解析引擎
    'DEFAULT_PARSER_CLASSES': [
        # 解析前端传来的json格式数据,若前端指定content-type=application/json
        # 就会使用此JSONParser解析器解析
        'rest_framework.parsers.JSONParser',
        # 解析前端传来的表单格式数据,若前端指定content-type=application/x-www-form-urlencoded
        # 就会使用此FormParser解析器解析
        'rest_framework.parsers.FormParser',
        # 解析前端传来的multipart-form-data格式数据,若前端指定content-type=multipart/form-data
        # 就会使用此MultiPartParser解析器解析
        'rest_framework.parsers.MultiPartParser',
    ],
}

4、上面两个配置查找顺序

  • 先从视图类中找,也就是我们所说的局部
  • 项目的配置文件–settings.py
  • drf默认的配置—> drf的settings.py—> DEFAULTS