接上回说到自定义DRF的序列化类,现在谈谈API响应后的JSON数据的包装,DRF加上分页器之后显示的包装数据如下:

Django restframework【微创】自定义(续)_DRF

这是没有做任何自定义原生DRF的分页器响应的数据结构,加了红框里面一些分页参数字段,并且将数据结果对象用一个列表嵌套起来和results形成键值对。

可实际的业务需求并不是如此,这只是DRF一厢情愿的初始作法,我们要想去掉一些字段,添加一些字段,修改一些字段,那么DRF提供自定义方法:

class myPagination(PageNumberPagination):
    page_size = 1
    page_query_param = 'page'
    page_size_query_param = "size"
    max_page_size = None

    #重写get_paginated_response方法,实现自定义返回值
    def get_paginated_response(self, data):
        return Response({
            "count": self.page.paginator.count,
            "datalist": data,               #觉得results不习惯,改成datalist也行
            "page": self.page.number,
            "pages": self.page.paginator.num_pages,
            "pagesize": self.page_size
        })

测试结果显示:

Django restframework【微创】自定义(续)_DRF_02

实际上,除了真正的业务数据还有每页显示的所有数据的总条目以外,其他的字段都是多余,因为在Vue的世界里使用element的分页组件传入一个total,它会全部帮你搞定:

Django restframework【微创】自定义(续)_DRF_03

如图,只有total这个参数需要从后端获取,其他都不是问题,所以,发展到前后端分离的今天DRF很多创始性的东西慢慢落伍了,那么就更依赖自定义了,弃其糟粕,取其精华。

光是上面这样还远远不够,前端找到你说,怎么连请求响应状态码都没有,还要依赖浏览器响应200才知道数据获取成功,太low了,需要马上解决这个问题。

我们看分页器显示的数据无非是在业务数据外层嵌套一层,最后还是用DRF的响应器Response去返回json数据流,分页器的这层嵌套外面还能再嵌套一层吗?当然可以,但是不建议在分页器里面处理了。

我们可以在响应器上面做点手脚,因为响应器本身就是干这个的,根据不同的场合响应不同类型的包装数据,我们来简单举例:

from rest_framework.response import Response
class JSonResponse(Response):
    def __init__(self, code=20000, msg="Success", data={}, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None):

        super(JSonResponse, self).__init__(data, status, template_name, headers,
                                           exception, content_type)

        self.data = {"code": code, "msg": msg, "data": data}

class myPagination(PageNumberPagination):
    page_size = 1
    page_query_param = 'page'
    page_size_query_param = "size"
    max_page_size = None

    #重写get_paginated_response方法,实现自定义返回值
    def get_paginated_response(self, data):
        return JSonResponse(data={
            "total": self.page.paginator.count,
            "datalist": data,               #觉得results不习惯,改成datalist也行
            "page": self.page.number,
            "pages": self.page.paginator.num_pages,
            "pagesize": self.page_size
        })

首先,我们仿照自定义分页类一样,先自定义一个响应器,继承原有的Response响应器,添加数据头部字段,注意data要接收一个字典类型,然后在get_paginated_response类的返回值函数Reponse改为我自定义的响应器JsonResponse,如此一来,两层嵌套都有了,各管各的,分页显示头由分页去处理,状态显示头由响应器去处理,测试结果如下:

Django restframework【微创】自定义(续)_DRF_04

这样得到一个大对象返回给前端去请求,code设为20000,前端收到这个数字即可判定数据请求成功,这个需求非常基础,几乎所有API都需要这么做,至于其他的要不要,看业务需求。