django-simple-captcha 是 django 项目中稳定兼容的选择,支持 django 4.x 和 python 3.9+;需 pip 安装、迁移数据库、配置 captcha_challenge_funct、url 路由及 form 中使用 captchafield,注意 session 中间件顺序与字段名不被覆盖。

django-simple-captcha 安装与基础配置
直接用 django-simple-captcha 是目前 Django 项目中最稳定、兼容性最好的选择,它不依赖 Pillow 的复杂配置,也不需要自己写视图生成图片逻辑。Django 4.x 和 Python 3.9+ 都支持,但要注意它默认使用 CAPTCHA_FONT_PATH 指向系统字体,Windows 下容易因路径或字体缺失导致 500 错误。
实操建议:
- 运行
pip install django-simple-captcha,然后在INSTALLED_APPS中加入'captcha' - 执行
python manage.py migrate—— 它会建一张captcha_captchastore表存验证码哈希和过期时间 - 在
settings.py中至少加一句:CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'(避免 Linux 服务器上因缺少中文字体而崩溃) - 别漏掉 URL 配置:
path('captcha/', include('captcha.urls')),否则/captcha/image/xxx.png会 404
在 Form 中嵌入验证码字段
不能直接在模板里写 HTML input + img 标签手动拼接,那样无法校验、也绕过 Django 表单安全机制。必须通过 CaptchaField 注入到 Form 类中,它会自动渲染隐藏字段 + 图片 URL + 刷新按钮。
实操建议:
- 定义 Form 时导入并添加字段:
from captcha.fields import CaptchaField,然后在类里写captcha = CaptchaField() - 如果想自定义错误提示,传参:
CaptchaField(error_messages={'invalid': '验证码不对,请重试'}) - 前端模板中只需
{{ form.captcha }},不要额外写<img>或 JS 刷新逻辑 ——captcha已内置刷新链接和 base64 fallback - 注意:该字段默认是必填的,若需可选校验(如非注册页),得重写
clean_captcha方法并手动清空验证逻辑
验证码校验失败却没报错?检查这几个点
常见现象是用户输错验证码,表单依然通过 is_valid(),或者报错但不显示在 captcha 字段下。根本原因通常是 session 或缓存未生效、或字段名被覆盖。
实操建议:
- 确认
MIDDLEWARE中有'django.contrib.sessions.middleware.SessionMiddleware',且顺序在'django.middleware.common.CommonMiddleware'之后 - 检查是否在视图中重复调用了
form = MyForm(request.POST or None)多次 —— 第二次实例化会丢失原始 POST 数据里的captcha_0和captcha_1隐藏字段 -
CaptchaField实际提交两个值:captcha_0(哈希 key)和captcha_1(用户输入),任何中间件或装饰器篡改request.POST都会导致校验跳过 - 开发时打开
DEBUG=True,留意日志里有没有CaptchaStore.get报None—— 很可能是 Redis 缓存未配置或 session 被清空
替换默认字体或支持中文?别硬改源码
django-simple-captcha 默认用 DejaVuSans.ttf,Linux 上可能缺失,Windows 上路径含空格又易出错。强行指定 CAPTCHA_FONT_PATH 到 simhei.ttf 等中文字体,常因编码或字形宽度不一致导致图片截断或 500。
实操建议:
- 优先用 ASCII 字符集:
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'(返回如 "3+5=?"),完全避开字体问题 - 真要中文,把字体文件放进项目目录(如
static/fonts/simhei.ttf),再用绝对路径赋值给CAPTCHA_FONT_PATH,并确保 Web 服务用户有读取权限 - 更稳妥的做法是换方案:用
django-redis+ 自定义 view 返回 base64 图片,配合前端 canvas 渲染 —— 但这就脱离了captcha的自动表单集成,得自己管过期、存储和校验
真正麻烦的不是生成图片,而是让每次请求的 key、session、数据库记录三者对得上。很多问题表面是“验证码不刷新”,实际是 CaptchaStore 表里没对应记录,或者 Redis 里 key 被提前删了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











