There are two things that need to happen here:
1. Customizable exception handling.
2. Appropriate hooks to allow customizing of non-exception responses.
Let's deal with these in turn:
The first needs an `EXCEPTION_HANDLER` setting, that takes an exception and returns an appropriate reponse (or None if it cannot be handled and should 500 error). I've done a little prep work to make fixing this easier - see this commit:
The exception handler now just needs to be set via an `EXCEPTION_HANDLER` setting that defaults to `'rest_framework.view.exception_handler'`. Plus of course a test and docs. You'll see that some logic is still handled in the view, which leaves a fairly small stub to override if you want to customize the style of exception responses.
The second I think needs a `get_success_response(data=None, created=False)` and `get_failure_response` hooks in the GenericAPIView. I think we should deprecate `get_success_headers` and move all the 200/201/204 logic into the `get_success_response` method.
def get_success_response(data=None, created=False):
status = HTTP_200_OK
headers = {}
if created:
status = HTTP_201_CREATED
headers = ... # same as existing `get_success_headers`
if data is None:
status = HTTP_204_NO_CONTENT
return Response(data, status=status, headers=headers)
def get_failure_response(errors):
return Response(status.HTTP_400_BAD_REQUEST)
That'd make it easy enough to customise non-exception responses (either the status codes, headers, or the response body), by creating a mixin and using that throughout, or by customizing them on a per-view basis.
Sound okay?... Presumably those two sets of changes would allow you to support your use case?