Django Rest Framework报错:'NoneType' object has no attribute 'token'
解决DRF中'NoneType' object has no attribute 'token'错误
这个错误的根源在于你UserCreateSerializer里的key字段配置有误,我来一步步帮你理清问题并解决:
问题分析
DRF默认的Token模型和User模型是一对一关联,反向关联的默认名称是auth_token(不是你写的key);同时,Token模型存储token字符串的字段是key(不是token)。你写的source='key.token'完全指向了不存在的属性:User对象没有key这个关联,就算有,token也不是Token模型的有效字段,所以访问时会得到None,进而触发NoneType属性错误。
解决方案
方案1:修正Serializer的字段配置
直接把key字段的source参数改成正确的关联和字段名:
from rest_framework import serializers from django.contrib.auth.models import User class UserCreateSerializer(serializers.ModelSerializer): """User django serilization""" # 修正source为正确的反向关联+Token字段 key = serializers.StringRelatedField(source='auth_token.key', read_only=True) class Meta: model = User fields = ['phonenumber','id','email', 'username', 'key' ] def create(self, validated_data): user = User(**validated_data) user.save() return user
这里auth_token是User与Token之间默认的反向关联名称,key是Token模型存储token字符串的字段,这样就能正确获取到用户的token值了。
方案2:兼容无Token的老用户(可选)
如果你的数据库里已经存在没有Token的老用户,直接用方案1会抛出Token.DoesNotExist异常(因为一对一关联的反向属性不存在时会报错)。这时候可以用SerializerMethodField来安全处理:
from rest_framework import serializers from django.contrib.auth.models import User from rest_framework.authtoken.models import Token class UserCreateSerializer(serializers.ModelSerializer): """User django serilization""" key = serializers.SerializerMethodField(read_only=True) class Meta: model = User fields = ['phonenumber','id','email', 'username', 'key' ] def get_key(self, obj): # 尝试获取token,不存在则返回None或空字符串 try: return obj.auth_token.key except Token.DoesNotExist: return None def create(self, validated_data): user = User(**validated_data) user.save() return user
额外检查:确保Token生成信号正常工作
你的post_save信号逻辑是对的,但要确认它被正确注册了:
- 如果信号写在
models.py里,不需要额外操作; - 如果放在单独的
signals.py文件中,需要在应用的apps.py里注册:
from django.apps import AppConfig class YourAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'your_app_name' def ready(self): import your_app_name.signals
然后在settings.py的INSTALLED_APPS里,把your_app_name替换成your_app_name.apps.YourAppConfig,确保信号在应用启动时被加载。
内容的提问来源于stack exchange,提问作者Babak Abadkheir
相关产品推荐
相关产品推荐

