类型为“AuthToken”的对象无法进行JSON序列化

15

在创建令牌时,我遇到了上述错误,请看代码:

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)
    })

我在这里做错了什么


1
你需要像对用户进行序列化一样,对AuthToken进行序列化(或传递该令牌的某个属性,该属性可以转换为JSON(例如strint等)。AuthToken本身是不可序列化的,至少不是没有额外逻辑的情况下。 - Willem Van Onsem
如何序列化AuthToken? - kzrfaisal
使用序列化器,就像您使用“UserSerializer”一样。 - Willem Van Onsem
1
好的,明白了,它是一个无法序列化的元组。尝试执行以下代码:AuthToken.objects.create(user)[1]。 - kzrfaisal
2
这似乎是django-rest-knox的变化。我有一个使用您在帖子中提供的代码的django-rest-know v 3.6.0项目。我刚开始一个新项目(使用版本4.0.1),我不得不将[1]添加到令牌序列化中。 - HenryM
4个回答

46

Token.objects.create 返回一个元组 (instance, token),因此要获取token,请使用索引1

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


2
但是这是否是我们需要使用的真正令牌呢?我的意思是,当我们打印 AuthToken.objects.create(user) 时,它会输出像这样的结果:(<AuthToken: long_token : username>, 'another_token'),而当我检查数据库时,“long_token”存储在数据库中,而不是“another_token”,但你正在使用的方法返回“another_token”。 - Irfan wani

15

更好的方法是在Python中使用该方法。

_, token = AuthToken.objects.create(user)
return Response({
    "user": UserSerializer(user, context=self.get_serializer_context()).data,
    "token": token
})

1
这个特定的错误是因为Token.objects.create返回一个元组(instance, token)。只需使用第二个位置[1]即可,而不是使用前者。
"token": AuthToken.objects.create(user)[1]

0
如果你正在使用Django rest framework auth token,请按照以下步骤操作:
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)



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接