一、说明
建立了几个文件
二、一步一步来
1、建立json_response.py 继承了 Response,
一共三个函数,成功、详情,错误
from rest_framework.response import Response
class SuccessResponse(Response):
"""
标准响应成功的返回, SuccessResponse(data)或者SuccessResponse(data=data)
(1)默认code返回2000, 不支持指定其他返回码
"""
def __init__(self, data=None, msg='success', status=None, template_name=None, headers=None, exception=False,
content_type=None,page=1,limit=1,total=1):
std_data = {
"code": 2000,
"page": page,
"limit": limit,
"total": total,
"data": data,
"msg": msg
}
super().__init__(std_data, status, template_name, headers, exception, content_type)
class DetailResponse(Response):
"""
不包含分页信息的接口返回,主要用于单条数据查询
(1)默认code返回2000, 不支持指定其他返回码
"""
def __init__(self, data=None, msg='success', status=None, template_name=None, headers=None, exception=False,
content_type=None,):
std_data = {
"code": 2000,
"data": data,
"msg": msg
}
super().__init__(std_data, status, template_name, headers, exception, content_type)
class ErrorResponse(Response):
"""
标准响应错误的返回,ErrorResponse(msg='xxx')
(1)默认错误码返回400, 也可以指定其他返回码:ErrorResponse(code=xxx)
"""
def __init__(self, data=None, msg='error', code=400, status=None, template_name=None, headers=None,
exception=False, content_type=None):
std_data = {
"code": code,
"data": data,
"msg": msg
}
super().__init__(std_data, status, template_name, headers, exception, content_type)
2、自定义异常处理函数 文件为exception.py
import logging
import traceback
from django.db.models import ProtectedError
from django.http import Http404
from rest_framework.exceptions import APIException as DRFAPIException, AuthenticationFailed, NotAuthenticated
from rest_framework.status import HTTP_401_UNAUTHORIZED
from rest_framework.views import set_rollback, exception_handler
from apps.utils.json_response import ErrorResponse
logger = logging.getLogger(__name__)
class CustomAuthenticationFailed(NotAuthenticated):
# 设置 status_code 属性为 400
status_code = 400
def CustomExceptionHandler(ex, context):
"""
统一异常拦截处理
目的:(1)取消所有的500异常响应,统一响应为标准错误返回
(2)准确显示错误信息
:param ex:
:param context:
:return:
"""
msg = ''
code = 4000
# 调用默认的异常处理函数
response = exception_handler(ex, context)
if isinstance(ex, AuthenticationFailed):
# 如果是身份验证错误
if response and response.data.get('detail') == "Given token not valid for any token type":
code = 401
msg = ex.detail
elif response and response.data.get('detail') == "Token is blacklisted":
# token在黑名单
return ErrorResponse(status=HTTP_401_UNAUTHORIZED)
else:
code = 401
msg = ex.detail
elif isinstance(ex, Http404):
code = 400
msg = "接口地址不正确"
elif isinstance(ex, DRFAPIException):
set_rollback()
msg = ex.detail
if isinstance(msg, dict):
for k, v in msg.items():
for i in v:
msg = "%s:%s" % (k, i)
elif isinstance(ex, ProtectedError):
set_rollback()
msg = "删除失败:该条数据与其他数据有相关绑定"
# elif isinstance(ex, DatabaseError):
# set_rollback()
# msg = "接口服务器异常,请联系管理员"
elif isinstance(ex, Exception):
logger.exception(traceback.format_exc())
msg = str(ex)
return ErrorResponse(msg=msg, code=code)
3、自定义分页处理 pagination.py
from collections import OrderedDict
from django.core import paginator
from django.core.paginator import Paginator as DjangoPaginator, InvalidPage
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
class CustomPagination(PageNumberPagination):
page_size = 10
page_size_query_param = "limit"
max_page_size = 999
django_paginator_class = DjangoPaginator
def paginate_queryset(self, queryset, request, view=None):
"""
Paginate a queryset if required, either returning a
page object, or `None` if pagination is not configured for this view.
"""
empty = True
page_size = self.get_page_size(request)
if not page_size:
return None
paginator = self.django_paginator_class(queryset, page_size)
page_number = request.query_params.get(self.page_query_param, 1)
if page_number in self.last_page_strings:
page_number = paginator