Object of type 'AuthToken' is not JSON serializable
Asked Answered
S

4

15

I'm getting the above error when creating token, here's the code:

from rest_framework import generics, permissions
from rest_framework.response import Response 
from knox.models import AuthToken
from .serializers import UserSerializer, RegisterSerializer

class RegisterAPI(generics.GenericAPIView):
    serializer_class = RegisterSerializer

def post(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    user = serializer.save()
    return Response({
        "user": UserSerializer(user, context=self.get_serializer_context()).data,
        "token": AuthToken.objects.create(user)
    })

what am I doing wrong here

Secessionist answered 13/4, 2019 at 17:58 Comment(5)
Well you will need to serialize the AuthToken as well, like you did with the user (or pass an attribute of that token that can be converted to JSON (like a str, int, etc.). An AuthToken itself is, at least not without some extra logic, serializable).Emulate
How to serialize AuthToken ?Secessionist
With a serializer, just like you did with the UserSerializer.Emulate
ok, got it, it's a tuple which can't be serialized, doing this worked AuthToken.objects.create(user)[1].Secessionist
This seems to be a change in django-rest-knox. I have a project with django-rest-know v 3.6.0 using the code you have in the post. I'm just starting an new project (using version 4.0.1), and I've had to add the [1] to the token serialization.Westland
B
47

The Token.objects.create returns a tuple (instance, token). So in order to get token use the index 1

"token": AuthToken.objects.create(user)[1]

Bilberry answered 27/4, 2019 at 14:10 Comment(1)
But is that the real token which we need to work with. What i mean is when we print AuthToken.objects.create(user) it gives output like this; (<AuthToken: long_token : username>, 'another_token') and when i checked the database, the "long_token" is stored in the database not the "another_token" but the method you are using returns "another_token".Gabriellia
M
15

Better way is use this method in python

_, token = AuthToken.objects.create(user)
return Response({
    "user": UserSerializer(user, context=self.get_serializer_context()).data,
    "token": token
})
Morgun answered 1/7, 2019 at 6:51 Comment(0)
B
1

This particular error occurs because the Token.objects.create returns a tuple (instance, token). just use the second position [1] by using instead of former

"token": AuthToken.objects.create(user)[1]
Bambara answered 17/5, 2020 at 18:35 Comment(0)
C
1

If you're using Django rest framework auth token do this:

from rest_framework.authtoken.models import Token

...
# The token will be in token variable, created variable will be a bool
token, created = Token.objects.get_or_create(user=request.user)

# Object of type Token is not JSON serializable, so convert token to string
token = str(token)


Covariance answered 30/11, 2023 at 17:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.