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)
In function based views we can pass extra context to serializer with "context" parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with "self. context". From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.
Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With