django rest framework 自定義返回方式
大家在用Django Rest Framework的時(shí)候會(huì)發(fā)現(xiàn)默認(rèn)繼承后,增刪改查的返回信息都是一段data,這是因?yàn)槲覍?shí)際是狀態(tài)碼和信息你在調(diào)用api的時(shí)候是看不到的,僅僅如此么?并不是這樣,在我前端調(diào)用后端的時(shí)候,實(shí)際上相關(guān)的code和msg是能看得到的,但是我們?cè)谄胀ǖ恼{(diào)用api他只是單單的返回data信息,這個(gè)是不夠我們滿足需求的,畢竟我們不僅僅需要用前端需調(diào)用,下面我們來(lái)自定義Response返回信息
Django(2.0)
Django Rest Framework
Python3.6
1、自定義Response,繼承rest framework的Response
#這個(gè)方法py文件我們可以寫到任意地方,目的是在我們需要寫一個(gè)Baseview的時(shí)候?qū)⒎呕胤椒ㄒ?
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、重寫B(tài)ase類,將增刪改查方法重寫并且返回方法為剛剛定義好的新的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視圖繼承以及測(cè)試
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")
這樣我們就完成了自定義返回信息,下一節(jié)將講解自定義異常
補(bǔ)充知識(shí):django rest framework 自定義異常返回
上一節(jié)給大家介紹了自定義Response返回信息,但那個(gè)只用于正確的返回success,但是當(dāng)我們用到了權(quán)限
auth 401、方法不允許method 405,等等,這時(shí)候我們就用自己自定義異常返回信息
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
#無(wú)需調(diào)用,報(bào)錯(cuò)的時(shí)候他自己會(huì)調(diào)用!!
以上這篇django rest framework 自定義返回方式就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Pytorch平均池化nn.AvgPool2d()使用方法實(shí)例
平均池化層,又叫平均匯聚層,下面這篇文章主要給大家介紹了關(guān)于Pytorch平均池化nn.AvgPool2d()使用方法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
使用python快速獲取PDF文件頁(yè)數(shù)的辦法
有時(shí)在處理或打印一個(gè)PDF文檔之前,你可能需要先知道該文檔包含多少頁(yè),對(duì)于程序員來(lái)說(shuō),編寫腳本來(lái)完成這項(xiàng)工作會(huì)更加高效,本文就介紹一個(gè)使用Python快速獲取PDF文件頁(yè)數(shù)的辦法,需要的朋友可以參考下2024-03-03
python十進(jìn)制和二進(jìn)制的轉(zhuǎn)換方法(含浮點(diǎn)數(shù))
這篇文章主要介紹了python十進(jìn)制和二進(jìn)制的轉(zhuǎn)換方法(含浮點(diǎn)數(shù)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
20行Python代碼實(shí)現(xiàn)一款永久免費(fèi)PDF編輯工具的實(shí)現(xiàn)
這篇文章主要介紹了20行Python代碼實(shí)現(xiàn)一款永久免費(fèi)PDF編輯工具的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
PyTorch 如何設(shè)置隨機(jī)數(shù)種子使結(jié)果可復(fù)現(xiàn)
這篇文章主要介紹了PyTorch 設(shè)置隨機(jī)數(shù)種子使結(jié)果可復(fù)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-05-05

