You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:03:07