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

Django DRF注册报Expected pk value received BoundField错误

Django注册接口序列化报错与403问题修复

问题表现

  • 注册流程抛出序列化校验错误:{'user': [ErrorDetail(string='Incorrect type. Expected pk value, received BoundField.', code='incorrect_type')]}
  • 注册接口/api/v1.0/user/register-patient/返回403 Forbidden状态码
  • 已确认PatientSerializer可正常将is_active=False的用户数据写入数据库,报错来源为TokenSerializer

根因分析

接口返回403并非权限配置问题,RegisterView已配置AllowAny权限,403是TokenSerializer校验失败后,代码走到固定错误返回分支导致的,具体错误点有3个:

  1. 用户ID传值类型错误:构造TokenSerializer入参时写的patient_serializer['id']拿到的是序列化器的BoundField实例,不是用户主键的整数值,DRF外键字段要求接收pk值(整数ID),类型不匹配直接触发类型错误。
  2. Token字段名不匹配:VerificatonToken模型和TokenSerializer中定义的验证令牌字段名为verification_token,但传参时错误使用了token作为key,序列化器无法读取到令牌值,校验直接失败。
  3. 邮箱验证逻辑隐患:PatientVerificationView中查询验证令牌时,错误使用了不存在的token字段作为查询条件,且未对查询结果做空判断,后续用户点击验证链接时会出现查询失败、空指针报错的问题。

修复方案

1. 修正注册接口中TokenSerializer的传参逻辑

找到RegisterView类中构造verification_token_serializer的代码块,替换为以下内容:

verification_token_serializer = TokenSerializer(
    data={
        # 通过patient_serializer.data取序列化后的输出字典,拿到整数类型的用户ID
        'user': patient_serializer.data['id'],
        # 字段名和模型/序列化器定义保持一致
        'verification_token': verification_token
    }
)

2. 修正邮箱验证接口的查询逻辑

找到PatientVerificationView类的get方法,替换查询逻辑为以下内容,补充空值判断避免报错:

def get(self, request, pk, format=None):
    print("Verifying Patient", pk)
    # 使用模型中实际存在的verification_token字段查询,先判断查询结果是否为空
    tokenObj = VerificatonToken.objects.filter(verification_token=pk).first()
    if not tokenObj:
        return Response('无效的验证链接', status=404)

    user = User.objects.filter(id=tokenObj.user.id).first()
    if user:
        patient_serializer = PatientSerializer(
            user, data={'is_active': True}, partial=True)
        if patient_serializer.is_valid(raise_exception=False):
            patient_serializer.save()
            return Response('Patient email verified', status=200)

    return Response(status=404)

注:更新用户时加上partial=True参数,允许部分字段更新,避免序列化器校验其他必填字段时抛出错误。

可选优化

模型类名VerificatonToken存在拼写错误(正确拼写应为VerificationToken),不影响当前运行,但建议修正以符合代码规范。

修复后流程验证

  1. 用户提交注册信息后,PatientSerializer正常保存is_active=False的用户记录
  2. TokenSerializer接收到正确类型的用户ID和匹配的字段名,校验通过后保存验证令牌
  3. 触发SendGrid发信逻辑,正常返回200状态码,不会再走到403错误分支
  4. 用户点击邮件链接时,可正确匹配到验证令牌,将用户is_active字段置为True,完成邮箱验证

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:06:28