'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 |
