PAYATHON 2026

Django Allauth 已设置 mandatory,为何仍无法启用邮箱验证码验证?

排障赵师傅

结论

这三行配置的设置名称和 "mandatory" 写法都正确。要确定报错原因,仍需检查报错进程实际加载了哪份配置,以及 Allauth 最终读到了什么值。

使用新版注册字段配置时,强制邮箱验证还要求 ACCOUNT_SIGNUP_FIELDS 包含 "email*"。这项检查与当前报错的条件不同,不能直接把缺少 "email*" 认定为报错原因。

为什么设置了 mandatory 还会报错?

Allauth 的配置检查源码中,这条报错的触发条件是:

app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED
and app_settings.EMAIL_VERIFICATION != app_settings.EmailVerificationMethod.MANDATORY

按这段逻辑,启用验证码验证后,如果 Allauth 读到的验证策略不等于 MANDATORY,就会报错。配置文件中的赋值是否生效,需要到运行中的进程里确认。

优先排查以下情况:

  • 启动时加载了另一份 settings,例如开发环境和生产环境使用了不同配置。
  • 后续导入的配置或重复赋值覆盖了 "mandatory"。
  • 环境变量解析后的值与预期不同。
  • 修改配置后,处理请求的服务进程尚未重启。

报错中的 VERFICATION 是报错字符串里的拼写错误。正确设置仍是 ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED,不要照着报错改名。

先检查运行时配置

在与报错服务相同的虚拟环境、容器和配置环境中运行:

python manage.py shell

然后执行:

import sys
import allauth
from importlib.metadata import version
from django.conf import settings
from allauth.account import app_settings

print("Python:", sys.executable)
print("django-allauth:", version("django-allauth"))
print("allauth path:", allauth.__file__)
print("settings module:", getattr(settings, "SETTINGS_MODULE", None))

print(
    "Django verification:",
    repr(getattr(settings, "ACCOUNT_EMAIL_VERIFICATION", None)),
)
print(
    "Django code enabled:",
    repr(getattr(settings, "ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED", None)),
)
print("Allauth verification:", repr(app_settings.EMAIL_VERIFICATION))
print("Allauth code enabled:", repr(app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED))
print(
    "Is mandatory:",
    app_settings.EMAIL_VERIFICATION
    == app_settings.EmailVerificationMethod.MANDATORY,
)

先看最后一项是否为 True,再根据输出排查。

如果 Django 读到的值不是 "mandatory",检查配置加载路径、重复赋值和环境变量。repr() 能帮助发现字符串前后的空格等问题。

Django 的值正确,但 Allauth 的比较结果为 False 时,需要检查已安装版本的配置读取逻辑,以及项目对设置的自定义处理。可以参考 Allauth 的设置读取源码,具体以当前环境安装的代码为准。

若比较结果为 True,服务仍报告同一错误,继续核对 shell 与报错服务是否使用同一份配置、同一个 Python 环境,并检查是否还有未重启的旧进程。

补齐邮箱必填配置

对于支持 ACCOUNT_SIGNUP_FIELDS 的版本,如果项目保留用户名注册,可以这样配置:

ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True

ACCOUNT_SIGNUP_FIELDS = [
    "username*",
    "email*",
    "password1*",
    "password2*",
]

"email*" 表示邮箱必填,"email" 表示邮箱选填。官方配置说明要求 "mandatory" 必须搭配 "email*"。

如果项目已自定义注册字段,在现有列表中补齐或修改邮箱项即可,保留业务所需的其他字段。若不使用用户名,注册字段还需与项目的登录方式保持一致。

缺少邮箱必填项时,配置检查会报错:

ACCOUNT_EMAIL_VERIFICATION = 'mandatory' requires 'email*' in ACCOUNT_SIGNUP_FIELDS

这项检查与题目中的验证码依赖检查各自独立。补上 "email*" 后,仍需确认运行时的验证策略是 "mandatory"。

修改后重启相关服务,并运行:

python manage.py check

版本和其他设置需要注意什么?

邮箱验证码验证功能从 django-allauth 64.2.0 开始提供。先确认安装版本,再查看对应版本的文档。如果需要升级,同时检查项目兼容性和升级说明,参见官方发布记录。

ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True 只影响通过邮件链接确认邮箱后的登录行为,对验证码验证无效,因此无法修复这条报错。参见登录配置说明。

为社交账号设置邮箱验证,也不会改变上述账户配置检查的判断条件。先查清 ACCOUNT_EMAIL_VERIFICATION 的实际读取值,再检查社交登录流程。

如果运行时输出均符合预期,错误仍能复现,请保留完整错误日志、Allauth 版本、启动方式和相关配置,以便进一步定位触发位置。仅凭现有信息,还无法确定是否为某个版本的缺陷。

备注:内容仅供参考。