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 sixfrom rest_framework.response import Responsefrom rest_framework.serializers import Serializerclass 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 serializersfrom assets import modelsfrom rest_framework.response import Responsefrom rest_framework import statusfrom rest_framework import viewsetsfrom rest_framework.decorators import actionfrom rest_framework.pagination import PageNumberPaginationfrom django.shortcuts import get_object_or_404from common.utils.custom_response import JsonResponsefrom rest_framework import filtersfrom django_filters import rest_frameworkfrom django_filters.rest_framework import DjangoFilterBackendclass 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_handlerdef 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 自定義返回方式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。
相關文章: