Django Rest Framework - 异常 、返回值处理 与 分页实现
2017-02-20 14:32
477 查看
一. 异常
在使用Django Rest Framework的时候,如果发生异常的话,往往如下面所示:{"detail": "Not allowed."}
但是后台往往想要的是常见的模式:
{ "desc":"Not allowed.", "code":400, "data":null }
官网文档 还是很清楚的,我们需要自定义 异常处理,然后配置就可以了,比如:
1. 实现
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: response.data['code'] = response.status_code response.data['desc'] = response.data['detail'] #response.data['data'] = None #可以存在 del response.data['detail'] #删除detail字段 return response
2. 配置
settings.py 中配置
REST_FRAMEWORK = { ... ... 'EXCEPTION_HANDLER': ( 'dataAPI.common.api_exception.custom_exception_handler' ) #'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler' }
二. 返回值
如异常所示,我们常常的返回值也是同样的类型 ,比如下面所示,基本数据格式和分页格式(后面说){ "desc":"page success", #描述信息 "code":200, #响应码 以 2开头就是成功 "data":{ "detail":Array[2], #当前页数据列表 "total":6, #页面总数 "page":2 #当前页面 } }
而我们使用Django Rest Framework 中 序列化的时候,直接就返回数据了,并不符合我们想要的数据,所以通过自定Response 进行数据返回 : 比如: 当然前提使用 APIView
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, desc=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, "desc": desc, "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
Example :
def get(self, request, house_pk): house = get_object_or_404(House, pk=house_pk) #获取数据 data = HouseSerializer(house) #序列化 return api_response.JsonResponse(data=data.data, code=status.HTTP_200_OK, desc='get house success') #使用上面的进行返回
结果:
success : 成功使用的是 JsonResponse 返回
{ "desc": "get house success", "code": 200, "data": { "pk": 7, "name": "VVVVVVV", "staff": { "phone": "xxxxxxxxxx", "username": "yuan" } } }
fail : 失败使用的是上面异常进行处理 : custom_exception_handler
{ "code": 404, "desc": "未找到。" }
三.分页实现
如 结果返回值所示,很多使用都需要实现分页功能,然而 Django Rest Framework 自带的分页功能,只能在mixins.ListModelMixin and generics.GenericAPIView classes继承这两个类才可以使用,而我们通常为了灵活性,往往会继承
APIView来实现,那么我们就需要自已使用分页功能。
数据基本格式:
{ "desc":"page success", #描述信息 "code":200, #响应码 以 2开头就是成功 "data":{ "detail":Array[2], #当前页数据列表 "total":6, #页面总数 "page":2 #当前页面 } }
这里我就使用在api 接口上,比如我的 (自已可以添加其他验证,比如page_size 最大是多少):
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from rest_framework import status from dataAPI.common import api_response #第二条中的返回值格式 JsonResponse def api_paging(objs, request, Serializer): """ objs : 实体对象 request : 请求对象 Serializer : 对应实体对象的序列化 """ try: page_size = int(request.GET.get('page_size', 2)) page = int(request.GET.get('page', 1)) except (TypeError, ValueError): return api_response.JsonResponse(code=status.HTTP_400_BAD_REQUEST, desc='page and page_size must be integer!') paginator = Paginator(objs, page_size) # paginator对象 total = paginator.num_pages #总页数 try: objs = paginator.page(page) except PageNotAnInteger: objs = paginator.page(1) except EmptyPage: objs = paginator.page(paginator.num_pages) serializer = Serializer(objs, many=True) #序列化操作 return api_response.JsonResponse(data={ 'detail': serializer.data, 'page': page, 'total': total }, code=status.HTTP_200_OK, desc='page success') #返回
Example :
def get(self, request, format=None): """ page_size : ?page=1&page_size=10 page : """ farms = self.get_object_list() #获取数据 return api_paginator.api_paging(farms, request, FarmSerializer) #分页处理,并返回
结果:
{ "desc": "page success", "code": 200, "data": { "detail": [ { "name": "V3", }, { "name": "V2", } ], "total": 6, #总页数 "page": 2 #当前页 } }
完
相关文章推荐
- django rest_framework比较完整的自定义实现样例
- django-rest-framework文件上传接口实现
- Django rest_framework自定义异常
- Django And Django-Rest-Framework 异常记录
- 商务综合管理-day2~5 分页实现,shiro(验证授权,MD5Hash加密),struts2全局异常处理
- Django处理URL过程与网站分页功能实现
- Django REST framework实现关键词检索
- 详解Django rest_framework实现RESTful API
- Django And Django-Rest-Framework 异常记录
- 基于.Net Framework 4.0 Web API开发(3):ASP.NET Web APIs 异常的统一处理Attribute 和统一写Log 的Attribute的实现
- (转)Django ====> 实战学习篇十三 分页(Paginator)处理;Django使用内置的admin
- django rest framework
- C++编译器怎么实现异常处理
- 一个用Spring AOP实现异常处理和记录程序执行时间的实例--邵京国
- Django REST framework
- Python3之Django Web框架分页多页码处理二
- django rest_framework--入门教程2
- Django1.8开发当中的异常处理
- django找不到模板(TemplateDoesNotExist at)的异常处理案例
- Django 之REST framework学习:解析器parser的使用