'Need to get a custom JSON response for the authentication login and registration page in django

viewset

class CustomRenderer(JSONRenderer):

    def render(self, data, accepted_media_type=None, renderer_context=None):
        status_code = renderer_context['response'].status_code
        response = {
          "status": "success",
          "code": status_code,
          "data": data,
          "message": None
        }

        if not str(status_code).startswith('2'):
            response["status"] = "error"
            response["data"] = None
            try:
                response["message"] = data["detail"]
            except KeyError:
                response["data"] = data

        return super(CustomRenderer, self).render(response, accepted_media_type, renderer_context)
        
class UserViewset(viewsets.ModelViewSet):
    renderer_classes = (CustomRenderer, ) 
    authentication_classes =[JWTAuthentication]            #ModelViewSet Provides the list, create, retrieve, update, destroy actions.
    permission_classes=(permissions.IsAdminUser,)    #admin authentication
    ##permission_classes = [HasValidJWT]
    queryset=models.Default_User.objects.all()
    serializer_class=serializers.UserDetailsSerializer

Urls.py

urlpatterns = [
    path('', TemplateView.as_view(template_name="social_app/index.html")), #social_app/index.html
    path('admin/', admin.site.urls),         #admin api
    path('api/',include(router.urls)),          #api
    path('accounts/', include('allauth.urls')),       #allauth
    re_path('rest-auth/', include('rest_auth.urls')),    #rest_auth
    path('api-auth/', include('rest_framework.urls')),
    re_path('/registration/', include('rest_auth.registration.urls')),
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    #path('auth/login/',TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('jobview/',view),
    path('timelog/',timelogview),
    path('chaining/', include('smart_selects.urls')),

]

I have created a custom JSON response for my API and i have given that JSON renderer in all my API viewsets and Iam getting the results as expected. But I need to get the same when I generate a token using JWT in the login page.

If I enter the username and password and post that in the url:http://127.0.0.1:8000/api/token/ Iam getting an output as

{
    "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY0OTQ4NjU0MSwiaWF0IjoxNjQ2ODk0NTQxLCJqdGkiOiI2ZWViYWRhZGY2YTU0M2ZkOTczYTQ5Y2RjNWM4OTdkZSIsInVzZXJfaWQiOj",
    "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjQ2ODk1NDQxLCJpYXQiOjE2NDY4OTQ1NDEsImp0aSI6ImZkMDA5OWRkNTA4NzQyNDk5MTg0MTUxYzU3MWRjYmU1IiwidXNlcl9pZCI6M"
}

But i need to get it as

{
    "status": "success",
    "code": 200,
    "data": [
    "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY0OTQ4NjU0MSwiaWF0IjoxNjQ2ODk0NTQxLCJqdGkiOiI2ZWViYWRhZGY2YTU0M2ZkOTczYTQ5Y2RjNWM4OTdkZSIsInVzZXJfaWQiOjF9.Rn8trTwVSTt29dMhFSAGZOoi7B758MQHwL1LJjSj_xo",
    "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjQ2ODk1NDQxLCJpYXQiOjE2NDY4OTQ1NDEsImp0aSI6ImZkMDA5OWRkNTA4NzQyNDk5MTg0MTUxYzU3MWRjYmU1IiwidXNlcl9pZCI6MX0.oQ4pHWMGXV_T1KBzXWZzvg2ceRuNUd5ci7-iZdevvB8"
]
 "message": null
}

It is the same for the auth registration also, it is not working for the authentication pages. Kindly help me to get that fixed as I am new to django.



Solution 1:[1]

You should create a specific serializer (not a Renderer) that inherit from TokenObtainPairSerializer to handle you json format and then create a new view that inherit from TokenObtainPairView view its serializer_class set to the previously created serializer, and use it in your router (not the default one).

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer from rest_framework_simplejwt.views import TokenObtainPairView

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)

        # Add custom claims
        token['name'] = user.name
        # ...

        return token

class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

ref: https://django-rest-framework-simplejwt.readthedocs.io/en/latest/customizing_token_claims.html

If you really want to use the renderer, you can just use your customer handler in the renderer_class attribute of your custom view.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sami Tahri