Skip to content

Instantly share code, notes, and snippets.

@IamMiracleAlex
Created February 27, 2023 21:00
Show Gist options
  • Save IamMiracleAlex/b7497e0b02d0e63522899045d6311eaf to your computer and use it in GitHub Desktop.
Save IamMiracleAlex/b7497e0b02d0e63522899045d6311eaf to your computer and use it in GitHub Desktop.
Standardise api responses to be consistent across board
from collections import OrderedDict
from rest_framework.response import Response
from rest_framework import status
from rest_framework.renderers import JSONRenderer
class SuccessResponse:
'''Standardise API Responses and add additional keys'''
def __new__(cls, data={}, detail = 'Success', status=status.HTTP_200_OK):
return Response(
{
'status': True,
'detail': detail,
'data': data
},
status
)
class FailureResponse:
def __new__(cls, detail = 'Error', status=status.HTTP_400_BAD_REQUEST):
return Response(
{
'status': False,
'detail': detail
},
status
)
class CustomJSONRenderer(JSONRenderer):
'''Override the default JSON renderer to be consistent and have additional keys'''
def render(self, data, accepted_media_type=None, renderer_context=None):
status = renderer_context['response'].status_code < 400
# when response data is a list, convert to dict
if isinstance(data, list):
data = {
'status': status,
'detail': 'Success' if status else 'Error',
'data': data
}
# if response data is none, convert to dict
if data is None:
data = {}
# if response data is not well formated dict, and not an error response, convert to right format
if isinstance(data, OrderedDict) and ('data' not in data) and ('non_field_errors' not in data):
data = {
'status': status,
'detail': 'Success' if status else 'Error',
'data': data,
}
# convert non_field_errors message to text, instead of list
if 'non_field_errors' in data:
data['detail'] = data.pop('non_field_errors')[0]
# if not `status` in response, add status
if not 'status' in data:
data['status'] = status
# if no `detail` in response, add detail based on status
if not 'detail' in data:
data['detail'] = 'Success' if status else 'Error'
return super().render(data, accepted_media_type, renderer_context)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment