Django REST framework custom format for all out responses Django REST framework custom format for all out responses angularjs angularjs

Django REST framework custom format for all out responses


After some research I found a way to do this. I had to override the default behaviour of the ModelViewSet to output a different response.

I created a custom Response format initially:

class ResponseInfo(object):    def __init__(self, user=None, **args):        self.response = {            "status": args.get('status', True),            "error": args.get('error', 200),            "data": args.get('data', []),            "message": args.get('message', 'success')        }

Then use this custom format in every method of the ModelViewSet:

class ResponseModelViewSet(viewsets.ModelViewSet):    def __init__(self, **kwargs):        self.response_format = ResponseInfo().response        super(ResponseModelViewSet, self).__init__(**kwargs)    def list(self, request, *args, **kwargs):        response_data = super(ResponseModelViewSet, self).list(request, *args, **kwargs)        self.response_format["data"] = response_data.data        self.response_format["status"] = True        if not response_data.data:            self.response_format["message"] = "List empty"        return Response(self.response_format)    def create(self, request, *args, **kwargs):        response_data = super(ResponseModelViewSet, self).create(request, *args, **kwargs)        self.response_format["data"] = response_data.data        self.response_format["status"] = True        return Response(self.response_format)    def retrieve(self, request, *args, **kwargs):        response_data = super(ResponseModelViewSet, self).retrieve(request, *args, **kwargs)        self.response_format["data"] = response_data.data        self.response_format["status"] = True        if not response_data.data:            self.response_format["message"] = "Empty"        return Response(self.response_format)    def update(self, request, *args, **kwargs):        response_data = super(ResponseModelViewSet, self).update(request, *args, **kwargs)        self.response_format["data"] = response_data.data        self.response_format["status"] = True        return Response(self.response_format)    def destroy(self, request, *args, **kwargs):        response_data = super(ResponseModelViewSet, self).destroy(request, *args, **kwargs)        self.response_format["data"] = response_data.data        self.response_format["status"] = True        return Response(self.response_format)


This would be more a more robust solution, as it can be used with Generic Views hassle free.

Also, the checks in render() can be easily altered as per the needs (Eg., handling no-2XX in this solution).

from rest_framework.renderers import JSONRendererclass CustomRenderer(JSONRenderer):    def render(self, data, accepted_media_type=None, renderer_context=None):        status_code = renderer_context['response'].status_code        response = {          "status": "success",          "code": status_code,          "data": data,          "message": None        }        if not str(status_code).startswith('2'):            response["status"] = "error"            response["data"] = None            try:                response["message"] = data["detail"]            except KeyError:                response["data"] = data        return super(CustomRenderer, self).render(response, accepted_media_type, renderer_context)