Я хочу создать API с помощью django-rest-framework. Пока мне удалось настроить одну конечную точку API и получить все элементы. Базовый ответ (без класса BaseResponse, описанного ниже) будет выглядеть так:

[
    {
        "uuid": "1db6a08d-ec63-4beb-8b41-9b042c53ab83",
        "created_at": "2018-03-12T19:25:07.073620Z",
        "updated_at": "2018-03-12T19:25:37.904350Z",
        "deleted_at": null,
        "random_name": "random name"
    }
]

Результат, которого я хотел бы достичь, будет примерно таким:

[
    "success": true
    "message": "Some exception message",
    "data" :{
        "uuid": "1db6a08d-ec63-4beb-8b41-9b042c53ab83",
        "created_at": "2018-03-12T19:25:07.073620Z",
        "updated_at": "2018-03-12T19:25:37.904350Z",
        "deleted_at": null,
        "random_name": "random name"
    }
]

Мне удалось добиться этого, создав класс BaseReponse, и я просто возвращаю BaseResponse.to_dict () (метод, который я создал внутри класса).

class BaseResponse(object):

    data = None
    success = False
    message = None

    def __init__(self, data, exception):
        self.data = data
        self.message = str(exception) if exception is not None else None
        self.success = exception is None

    def to_dict(self):
        return {
            'success': self.success,
            'message': self.message,
            'data': self.data,
        }

Посмотреть:

class RandomModelList(APIView):

    def get(self, request, format=None):
        exception = None
        models = None
        try:
            models = RandomModel.objects.all()
        except Exception as e:
            exception = e
        serializer = RandomModelSerializer(models, many=True)

        base_response = BaseResponse(data=serializer.data, exception=exception)

        return Response(base_response.to_dict())

Я хочу упомянуть, что с текущим кодом все работает так, как ожидалось, но у меня есть огромный дубль в коде (мне просто кажется, что я заново изобрел колесо). Может ли кто-нибудь сказать мне, является ли это оптимальным решением моей проблемы, и если нет, что мне следует изменить / использовать?

2
Alec 14 Мар 2018 в 23:36

1 ответ

Лучший ответ

Вместо этого вы можете создать Custom Renderer. Что-то вроде

class CustomRenderer(JSONRenderer):

    def render(self, data, accepted_media_type=None, renderer_context=None):
        resp = {
        'data': data
        }
        return super(CustomRenderer, self).render(resp, accepted_media_type, renderer_context)

Затем создайте промежуточное ПО, например

class CustomResponseMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response.data.update({'success': is_client_error(response.status_code) or is_server_error(response.status_code)})
    return response
1
Shaumux 21 Мар 2018 в 12:50