Skip to content

Instantly share code, notes, and snippets.

@mark-mishyn
Last active June 20, 2017 18:04
Show Gist options
  • Save mark-mishyn/ec4f21ddc25e5b67a889e3f6f077923f to your computer and use it in GitHub Desktop.
Save mark-mishyn/ec4f21ddc25e5b67a889e3f6f077923f to your computer and use it in GitHub Desktop.
DRF Flat Errors Response
"""
Monkey patch for Response class in Django REST Framework.
Original response's data will be accessible by key "data"
and errors have flat format, so it is easier to handle
errors on client side.
"""
from django.utils import six
from rest_framework.response import Response
from rest_framework.serializers import Serializer
def get_data(data, status_code):
if status_code < 400:
return {
'data': data,
'success': True,
'errors': [],
}
errors = []
if not isinstance(data, dict) or not data:
errors.append({'field': None, 'message': 'Not described error'})
else:
for key, error in data.items():
if key in ('non_field_errors', 'detail'):
key = None
if isinstance(error, str): # for status code in range [401, 500]
errors.append({'field': key, 'message': error})
elif isinstance(error, list): # for status code 400
for e in error:
if isinstance(e, str):
errors.append({'field': key, 'message': e})
else:
errors.append({'field': None, 'message': 'Unknown error'})
else:
errors.append({'field': None, 'message': 'Unknown error'})
return {
'data': {},
'success': False,
'errors': errors,
}
def __init__(self, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None):
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 = get_data(data, self.status_code)
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
Response.__init__ = __init__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment