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自定义返回方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。