坐看云起时|

一枚码农

园龄:7年6个月粉丝:5关注:1

drf 自定义返回格式与公共类定义

1.自定义异常处理(custom_exception.py)

点击查看代码
# 自定义异常处理
from rest_framework.views import exception_handler
from rest_framework.views import Response
from rest_framework import status


# 将仅针对由引发的异常生成的响应调用异常处理程序。它不会用于视图直接返回的任何响应
def custom_exception_handler(exc, context):
    response = exception_handler(exc, context)

    # 这个循环是取第一个错误的提示用于渲染
    for index, value in enumerate(response.data):
        if index == 0:
            key = value
            value = response.data[key]

            if isinstance(value, str):
                message = value
            else:
                message = key + value[0]

    if response is None:
        # print(exc)    #错误原因   还可以做更详细的原因,通过判断exc信息类型
        # print(context)  #错误信息
        # print('1234 = %s - %s - %s' % (context['view'], context['request'].method, exc))
        return Response({
            'message': '服务器错误'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)

    else:
        # print('123 = %s - %s - %s' % (context['view'], context['request'].method, exc))
        return Response({
            'message': message,
        }, status=response.status_code, exception=True)

    return response

2.自定义正常返回(render_response.py)

点击查看代码
'''
自定义返回处理
'''

# 导入控制返回的JSON格式的类
from rest_framework.renderers import JSONRenderer


class MyRender(JSONRenderer):
    # 重构render方法
    def render(self, data, accepted_media_type=None, renderer_context=None):
        if renderer_context:
            if isinstance(data, dict):
                msg = data.pop('msg', '成功')
                code = data.pop('code', 0)
                data = data.pop('data', data)
                if isinstance(data, list):
                    data = {
                        'total': len(data),
                        'data': data
                    }
            elif isinstance(data, list):
                msg = '成功'
                code = 0
                data = {
                    'total': len(data),
                    'data': data
                }
            else:
                msg = 'success'
                code = 0

            # 重新构建返回的JSON字典
            for key in data:
                # 判断是否有自定义的异常的字段
                if key == 'message':
                    msg = data[key]
                    data = ''
                    code = 1

            ret = {
                'msg': msg,
                'code': code,
                'data': data,
            }
            # 返回JSON数据
            return super().render(ret, accepted_media_type, renderer_context)
        else:
            return super().render(data, accepted_media_type, renderer_context)


通过以上三步,drf返回的数据格式就会变成以下形式
单个返回:
image
批量返回
image
异常返回
image


优化

通过上边三不,就可以实现有状态码的返回报文。但是状态码就是在自定义返回中写的01两种。如果需要其他状态码,就需要用
return Response({'code': 111, 'msg': 'hahah', 'data': qs})
这种形式组报文。对于这种,可以重写Response来优化。
重写Response
点击查看代码
from rest_framework.response import Response
class APIResponse(Response):
    def __init__(self, code=0, msg='success', data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None, **kwargs):
        dic = {'code': code, 'msg': msg}
        if data:
            dic['data'] = data
        if kwargs:
            dic.update(kwargs)

        super().__init__(data=dic, status=status,
                         template_name=template_name, headers=headers,
                         exception=exception, content_type=content_type)
用重写的Response类返回数
 qs = list(Camp.objects.filter(status=0).values())
 return APIResponse(qs)

drf公共类

使用上边重写后的APIResponse,并对分页重写。
点击查看代码
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet


class APIResponse(Response):
    def __init__(self, code=0, msg='成功', data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None, **kwargs):
        dic = {'code': code, 'msg': msg}
        if data:
            dic['data'] = data
        if kwargs:
            dic.update(kwargs)

        super().__init__(data=dic, status=status,
                         template_name=template_name, headers=headers,
                         exception=exception, content_type=content_type)


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 100
    page_size_query_param = 'page_size'
    max_page_size = 1000


class DRFBaseViewSet(ModelViewSet):
    pagination_class = StandardResultsSetPagination

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return APIResponse(data=serializer.data)

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return APIResponse(data=serializer.data)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return APIResponse(data=serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return APIResponse(data=serializer.data)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        return APIResponse(status=status.HTTP_204_NO_CONTENT)

本文作者:一枚码农

本文链接:https://www.cnblogs.com/yimeimanong/p/16185229.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   一枚码农  阅读(729)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
 
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Sold Out Hawk
  2. 2 光辉岁月 Beyond
Sold Out - Hawk
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : Jon Steingard

作曲 : Jon Steingard

I ain't like no one you met before

I'm running for the front

When they're all running for the door

And I won't sit down won't back out

You can't ever shut me up

Cause I'm on a mission

And I won't quit now

In a world full of followers

I'll be a leader

In a world full of doubters

I'll be a believer

I'm stepping out without a hesitation

Because the battle's already been won

I'm sold out

I'm no longer living

Just for myself

Running after Jesus

With my whole heart

And now I'm ready to show

I am sold out

I'm sold out

With every single

Step that I take now

With every drop of blood

Left in my veins

I'm gonna be making it count

I am sold out

This ain't just some temporary phase

You can't face this kind of grace

And leave the way you came

This is permanent with intent

And there won't be no stopping it now

I'm on a mission and it's heaven sent

In a world full of followers

I'll be a leader

In a world full of doubters

I'll be a believer

I'm stepping out without a hesitation

Cause my soul is like a stadium

I'm sold out

I'm no longer living

Just for myself

Running after Jesus

With my whole heart

And now I'm ready to shout

I am sold out

I'm sold out

With every single

Step that I take now

With every drop of blood

Left in my veins

I'm gonna be making it count

I am sold out

No trials coming against me

Could put a dent in my passion

They're just an opportunity

To put my faith into action

In a world full of followers

I'll be a leader

In a world full of doubters

I'll be a believer

I'm stepping out without a hesitation

I ain't got nothing left to be afraid of

I'm sold out

I'm no longer living

Just for myself

Running after Jesus

With my whole heart

And now I'm ready to show

I am sold out

I'm sold out

With every single

Step that I take now

With every drop of blood

Left in my veins

I'm gonna be making it count

I am sold out