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

如何自定义TokenObtainPairSerializer字段,仅保留phone_number为必填项

自定义TokenObtainPairSerializer仅保留phone_number为唯一必填字段

默认情况下,TokenObtainPairSerializer会要求传入username和password两个必填字段,路由配置如下:

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view())
]

未填写时会返回必填字段提示:

{
    "username": [
        "This field is required."
    ],
    "password": [
        "This field is required."
    ]
}

如果想要仅用phone_number作为唯一必填字段,直接添加该字段到自定义序列化器里是不够的——父类的username和password依然会被标记为必填。解决方法需要两步:显式覆盖父类字段并设为非必填,同时重写验证逻辑以适配phone_number。

完整实现代码

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from django.contrib.auth import get_user_model

User = get_user_model()

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    # 覆盖父类的username和password,标记为非必填
    username = serializers.CharField(required=False)
    password = serializers.CharField(required=False, write_only=True)
    # 定义必填的phone_number字段
    phone_number = serializers.CharField(max_length=10, required=True)

    def validate(self, attrs):
        # 提取并校验phone_number
        phone_number = attrs.get('phone_number')
        if not phone_number:
            raise serializers.ValidationError({"phone_number": ["该字段为必填项"]})
        
        # 根据手机号查找用户(需确保User模型中phone_number字段唯一)
        try:
            user = User.objects.get(phone_number=phone_number)
        except User.DoesNotExist:
            raise serializers.ValidationError({"phone_number": ["该手机号未注册"]})
        
        # 将用户对象传入attrs,供父类生成token使用
        attrs['user'] = user
        # 调用父类方法生成token数据
        data = super().validate(attrs)
        
        # 可在此处添加额外响应字段(如用户昵称、权限等)
        return data

class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

关键说明

  1. 覆盖父类字段:通过显式定义username和password并设置required=False,可以移除它们的必填要求。
  2. 重写validate方法:父类原有的验证逻辑依赖username和password,因此需要替换为基于phone_number的用户查找逻辑,确保能正确获取用户对象以生成JWT Token。
  3. 用户模型要求:你的User模型必须包含phone_number字段,且建议设置为唯一约束,避免查找用户时出现多条匹配的情况。

如果你的场景是短信验证码登录,还可以在validate方法中添加验证码校验逻辑(比如对比传入的code和缓存中的验证码),验证通过后再继续生成Token。

内容的提问来源于stack exchange,提问作者meg hidey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:35:20