Last active
June 20, 2017 18:04
-
-
Save mark-mishyn/ec4f21ddc25e5b67a889e3f6f077923f to your computer and use it in GitHub Desktop.
DRF Flat Errors Response
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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