django-rest格式化和相关方法

##格式化

后续所有的Rest请求都采用如下请求模式

1. token

token由于是单独的接口,并使用原生的django-rest-framework接口,所以采用如下的返回模式

{
    "access_token": "JbAornhQy4Qt5nsP1OZreZ4ZrEeyCf",
    "expires_in": 36000,
    "token_type": "Bearer",
    "scope": "read write groups",
    "refresh_token": "3Mb7hKGhTmn71jxeSqaIhUPk92Yics"
}

2. 调用失败情况

{
    "code": 401,
    "desc": "Authentication credentials were not provided."
}

3. 调用成功情况

{
    "code": 200,
    "desc": "get category list success",
    "data": [
        {
            "id": 1,
            "category_name": "活动",
            "category_color": "bg-success"
        },
        {
            "id": 2,
            "category_name": "课程",
            "category_color": "bg-info"
        },
        {
            "id": 3,
            "category_name": "咨询",
            "category_color": "bg-primary"
        }
    ]
}

##配置方式

utils.py

from rest_framework.views import exception_handler
from django.utils import six
from rest_framework.response import Response
from rest_framework.serializers import Serializer


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']
        del response.data['detail']  # 删除detail字段

    return response


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

setting.py中的配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'EXCEPTION_HANDLER': (
        'scaffolding.utils.custom_exception_handler'
    )
}

调用中的配置:

@api_view(['GET'])
def category_list(request):
    '''
    查询当前用户可以看到的所有活动目录
    :param request:
    :return:
    '''
    if request.method == 'GET':
        category_list = [];
        if request.user.is_staff:
            category_list = TimeCategory.objects.all()
        else:
            # 后续可以给用户一些专用的category
            category_list = TimeCategory.objects.filter(id=2)
        serializer = CategoryListSerializer(category_list, many=True)
        return JsonResponse(data=serializer.data, code=status.HTTP_200_OK, desc="get category list success")

posted @ 2021-11-21 17:42  yourwilliam  阅读(107)  评论(0)    收藏  举报