Reputation: 4180
So, I have the following:
class ObjectViewSet(
mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet
):
"""
REST API endpoints for Objects.
"""
serializer_class = ObjectSerializer
queryset = Object.objects.all()
This returns, say, for a list GET
request:
[
{
"uuid": "787573a2-b4f1-40df-9e3a-8555fd873461",
},
{
"uuid": "2ab56449-1be1-47d7-aceb-a9eaefa49665",
}
]
However, how could I slightly alter this response for mixins to be similar to the following:
{
success: true,
message: 'Some Extra Useful Message',
data: [
{
"uuid": "787573a2-b4f1-40df-9e3a-8555fd873461",
},
{
"uuid": "2ab56449-1be1-47d7-aceb-a9eaefa49665",
}
]
}
Is this possible, or should I just write my own custom endpoint Response()
and not utilise DRF's mixins
capability?
So, essentially, switching the custom:
Response(data, status=None, template_name=None, headers=None, content_type=None)
To:
response = {
'success': true,
'message': 'Some Extra Useful Message',
'data': serializer.data
}
Response(response, status=None, template_name=None, headers=None, content_type=None)
Upvotes: 12
Views: 4644
Reputation: 126
After long research, I found this useful and most appropriate to use. For such use cases one must refer to this documentation. In your case, you can do the following -
Declare a class renderer.py
from rest_framework.renderers import JSONRenderer
from rest_framework.utils import json
class JSONResponseRenderer(JSONRenderer):
# media_type = 'text/plain'
# media_type = 'application/json'
charset = 'utf-8'
def render(self, data, accepted_media_type=None, renderer_context=None):
response_dict = {
'status': 'failure',
'data': data,
'message': '',
}
data = response_dict
return json.dumps(data)
Update your settings.py
REST_FRAMEWORK = {
# Other code
'DEFAULT_RENDERER_CLASSES': (
'<app-name>.renderer.JSONResponseRenderer',
)
}
Update your ViewSet class
class YourViewSet(viewsets.ModelViewSet):
# Other code
renderer_classes = [JSONResponseRenderer]
And you're all set! Also refer to this post more.
Upvotes: 8
Reputation: 637
You can handle this response format using Middelwares
. If based on status code you have a fixed format for a response, then write a middleware.
class ResponseFormatMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
try:
if (not getattr(response, 'error', False)) and (isinstance(response.data, dict) or isinstance(response.data, list)):
response.data = {'success': True, 'message':'some message','data': response.data}
except AttributeError:
pass
return response
Middleware is written in CustomMiddleware
module as middleware.py
, then add
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'CustomMiddleware.middleware.ResponseFormatMiddleware', # Added this line
]
in settings.py
file.
Upvotes: 3