django rest framework 自定义返回方式

大家在用Django Rest Framework的时候会发现默认继承后,增删改查的返回信息都是一段data,这是因为我实际是状态码和信息你在调用api的时候是看不到的,仅仅如此么?并不是这样,在我前端调用后端的时候,实际上相关的code和msg是能看得到的,但是我们在普通的调用api他只是单单的返回data信息,这个是不够我们满足需求的,毕竟我们不仅仅需要用前端需调用,下面我们来自定义Response返回信息

Django(2.0)

Django Rest Framework

Python3.6

1、自定义Response,继承rest framework的Response

#这个方法py文件我们可以写到任意地方,目的是在我们需要写一个Baseview的时候将放回方法引用

from django.utils import six

from rest_framework.response import Response

from rest_framework.serializers import Serializer

class JsonResponse(Response):

"""

An HttpResponse that allows its data to be rendered into

arbitrary media types.

"""

def __init__(self, data=None, code=None, msg=None,

status=None,

template_name=None, headers=None,

exception=False, content_type=None):

"""

Alters the init arguments slightly.

For example, drop 'template_name', and instead use 'data'.

Setting 'renderer' and 'media_type' will typically be deferred,

For example being set automatically by the `APIView`.

"""

super(Response, self).__init__(None, status=status)

if isinstance(data, Serializer):

msg = (

'You passed a Serializer instance as data, but '

'probably meant to pass serialized `.data` or '

'`.error`. representation.'

)

raise AssertionError(msg)

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

self.template_name = template_name

self.exception = exception

self.content_type = content_type

if headers:

for name, value in six.iteritems(headers):

self[name] = value

2、重写Base类,将增删改查方法重写并且返回方法为刚刚定义好的新的Response类

#Base类,将增删改查方法重写

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from assets import serializers

from assets import models

from rest_framework.response import Response

from rest_framework import status

from rest_framework import viewsets

from rest_framework.decorators import action

from rest_framework.pagination import PageNumberPagination

from django.shortcuts import get_object_or_404

from common.utils.custom_response import JsonResponse

from rest_framework import filters

from django_filters import rest_framework

from django_filters.rest_framework import DjangoFilterBackend

class CustomViewBase(viewsets.ModelViewSet):

# pagination_class = LargeResultsSetPagination

# filter_class = ServerFilter

queryset = ''

serializer_class = ''

permission_classes = ()

filter_fields = ()

search_fields = ()

filter_backends = (rest_framework.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter,)

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 JsonResponse(data=serializer.data,msg="success",code=201,status=status.HTTP_201_CREATED,headers=headers)

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 JsonResponse(data=serializer.data,code=200,msg="success",status=status.HTTP_200_OK)

def retrieve(self, request, *args, **kwargs):

instance = self.get_object()

serializer = self.get_serializer(instance)

return JsonResponse(data=serializer.data,code=200,msg="success",status=status.HTTP_200_OK)

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 JsonResponse(data=serializer.data,msg="success",code=200,status=status.HTTP_200_OK)

def destroy(self, request, *args, **kwargs):

instance = self.get_object()

self.perform_destroy(instance)

return JsonResponse(data=[],code=204,msg="delete resource success",status=status.HTTP_204_NO_CONTENT)

3、view视图继承以及测试

class BatchLoadView(CustomViewBase):

queryset = models.Manufacturer.objects.all()

serializer_class = serializers.ManufacturerSerializer

def list(self, request, *args, **kwargs):

return JsonResponse(code=200, data=[], msg="testings")

这样我们就完成了自定义返回信息,下一节将讲解自定义异常

补充知识:django rest framework 自定义异常返回

上一节给大家介绍了自定义Response返回信息,但那个只用于正确的返回success,但是当我们用到了权限

auth 401、方法不允许method 405,等等,这时候我们就用自己自定义异常返回信息

1、定义settings配置文件

#定义异常返回的路径脚本位置

REST_FRAMEWORK = {

'EXCEPTION_HANDLER': 'common.utils.custom_execption.custom_exception_handler',

}

2、定义脚本

#注意,脚本路径需要与settings.py 定义的一样

from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):

# Call REST framework's default exception handler first,

# to get the standard error response.

response = exception_handler(exc, context)

# Now add the HTTP status code to the response.

if response is not None:

print(response.data)

response.data.clear()

response.data['code'] = response.status_code

response.data['data'] = []

if response.status_code == 404:

try:

response.data['message'] = response.data.pop('detail')

response.data['message'] = "Not found"

except KeyError:

response.data['message'] = "Not found"

if response.status_code == 400:

response.data['message'] = 'Input error'

elif response.status_code == 401:

response.data['message'] = "Auth failed"

elif response.status_code >= 500:

response.data['message'] = "Internal service errors"

elif response.status_code == 403:

response.data['message'] = "Access denied"

elif response.status_code == 405:

response.data['message'] = 'Request method error'

return response

#无需调用,报错的时候他自己会调用!!

以上这篇django rest framework 自定义返回方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是 django rest framework 自定义返回方式 的全部内容, 来源链接: utcz.com/z/317858.html

回到顶部