django rest framework 自定义返回方式
大家在用DjangoRestFramework的时候会发现默认继承后,增删改查的返回信息都是一段data,这是因为我实际是状态码和信息你在调用api的时候是看不到的,仅仅如此么?并不是这样,在我前端调用后端的时候,实际上相关的code和msg是能看得到的,但是我们在普通的调用api他只是单单的返回data信息,这个是不够我们满足需求的,毕竟我们不仅仅需要用前端需调用,下面我们来自定义Response返回信息
Django(2.0)
DjangoRestFramework
Python3.6
1、自定义Response,继承restframework的Response
#这个方法py文件我们可以写到任意地方,目的是在我们需要写一个Baseview的时候将放回方法引用
fromdjango.utilsimportsix
fromrest_framework.responseimportResponse
fromrest_framework.serializersimportSerializer
classJsonResponse(Response):
"""
AnHttpResponsethatallowsitsdatatoberenderedinto
arbitrarymediatypes.
"""
def__init__(self,data=None,code=None,msg=None,
status=None,
template_name=None,headers=None,
exception=False,content_type=None):
"""
Alterstheinitargumentsslightly.
Forexample,drop'template_name',andinsteaduse'data'.
Setting'renderer'and'media_type'willtypicallybedeferred,
Forexamplebeingsetautomaticallybythe`APIView`.
"""
super(Response,self).__init__(None,status=status)
ifisinstance(data,Serializer):
msg=(
'YoupassedaSerializerinstanceasdata,but'
'probablymeanttopassserialized`.data`or'
'`.error`.representation.'
)
raiseAssertionError(msg)
self.data={"code":code,"message":msg,"data":data}
self.template_name=template_name
self.exception=exception
self.content_type=content_type
ifheaders:
forname,valueinsix.iteritems(headers):
self[name]=value
2、重写Base类,将增删改查方法重写并且返回方法为刚刚定义好的新的Response类
#Base类,将增删改查方法重写
#!/usr/bin/envpython
#-*-coding:utf-8-*-
fromassetsimportserializers
fromassetsimportmodels
fromrest_framework.responseimportResponse
fromrest_frameworkimportstatus
fromrest_frameworkimportviewsets
fromrest_framework.decoratorsimportaction
fromrest_framework.paginationimportPageNumberPagination
fromdjango.shortcutsimportget_object_or_404
fromcommon.utils.custom_responseimportJsonResponse
fromrest_frameworkimportfilters
fromdjango_filtersimportrest_framework
fromdjango_filters.rest_frameworkimportDjangoFilterBackend
classCustomViewBase(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,)
defcreate(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)
returnJsonResponse(data=serializer.data,msg="success",code=201,status=status.HTTP_201_CREATED,headers=headers)
deflist(self,request,*args,**kwargs):
queryset=self.filter_queryset(self.get_queryset())
page=self.paginate_queryset(queryset)
ifpageisnotNone:
serializer=self.get_serializer(page,many=True)
returnself.get_paginated_response(serializer.data)
serializer=self.get_serializer(queryset,many=True)
returnJsonResponse(data=serializer.data,code=200,msg="success",status=status.HTTP_200_OK)
defretrieve(self,request,*args,**kwargs):
instance=self.get_object()
serializer=self.get_serializer(instance)
returnJsonResponse(data=serializer.data,code=200,msg="success",status=status.HTTP_200_OK)
defupdate(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)
ifgetattr(instance,'_prefetched_objects_cache',None):
#If'prefetch_related'hasbeenappliedtoaqueryset,weneedto
#forciblyinvalidatetheprefetchcacheontheinstance.
instance._prefetched_objects_cache={}
returnJsonResponse(data=serializer.data,msg="success",code=200,status=status.HTTP_200_OK)
defdestroy(self,request,*args,**kwargs):
instance=self.get_object()
self.perform_destroy(instance)
returnJsonResponse(data=[],code=204,msg="deleteresourcesuccess",status=status.HTTP_204_NO_CONTENT)
3、view视图继承以及测试
classBatchLoadView(CustomViewBase): queryset=models.Manufacturer.objects.all() serializer_class=serializers.ManufacturerSerializer deflist(self,request,*args,**kwargs): returnJsonResponse(code=200,data=[],msg="testings")
这样我们就完成了自定义返回信息,下一节将讲解自定义异常
补充知识:djangorestframework自定义异常返回
上一节给大家介绍了自定义Response返回信息,但那个只用于正确的返回success,但是当我们用到了权限
auth401、方法不允许method405,等等,这时候我们就用自己自定义异常返回信息
1、定义settings配置文件
#定义异常返回的路径脚本位置
REST_FRAMEWORK={
'EXCEPTION_HANDLER':'common.utils.custom_execption.custom_exception_handler',
}
2、定义脚本
#注意,脚本路径需要与settings.py定义的一样
fromrest_framework.viewsimportexception_handler
defcustom_exception_handler(exc,context):
#CallRESTframework'sdefaultexceptionhandlerfirst,
#togetthestandarderrorresponse.
response=exception_handler(exc,context)
#NowaddtheHTTPstatuscodetotheresponse.
ifresponseisnotNone:
print(response.data)
response.data.clear()
response.data['code']=response.status_code
response.data['data']=[]
ifresponse.status_code==404:
try:
response.data['message']=response.data.pop('detail')
response.data['message']="Notfound"
exceptKeyError:
response.data['message']="Notfound"
ifresponse.status_code==400:
response.data['message']='Inputerror'
elifresponse.status_code==401:
response.data['message']="Authfailed"
elifresponse.status_code>=500:
response.data['message']="Internalserviceerrors"
elifresponse.status_code==403:
response.data['message']="Accessdenied"
elifresponse.status_code==405:
response.data['message']='Requestmethoderror'
returnresponse
#无需调用,报错的时候他自己会调用!!
以上这篇djangorestframework自定义返回方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。