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

Django:如何实现django-simple-captcha验证码单独刷新功能?

问题描述

我有一个包含多个字段和验证码的注册表单,刚接触django-simple-captcha,想做一个仅单独刷新验证码的按钮。请问这个需求可行吗?应该怎么编写对应的实现函数?以下是我当前的代码:

register.html

<div><input type="text" name="studentId"></div>
<div><input type="text" name="Name"></div>
...
<div>{{ form.captcha }}</div>
<button type="button" class="btn">Refresh</button> <!-- 刷新验证码 -->
<button type="submit" class="btn btn-primary">Submit</button>

forms.py

from captcha.fields import CaptchaField

class MyForm(forms.Form):
    captcha = CaptchaField()

views.py

from .forms import MyForm

def preRegistration(request):
    form = MyForm(request.POST)
    if request.method == 'GET':
        return render(request, 'registration_form.html', {"form": form})
    if request.method == 'POST':
       studentId = request.POST.get('studentId') ... 
       if form.is_valid():
          Applicant.objects.create(studentID=studentID, ...)
          return render(request, 'login.html')
       else: 
          messages.error(request, 'Wrong Captcha!')
          return render(request, 'registration.html', {"form": form})

def refreshCaptcha():
    ...

解决方案

这个需求完全可行,通过后端生成新的验证码实例,前端用AJAX请求替换验证码图片和隐藏字段就能实现。具体步骤如下:

1. 修正原视图的初始化错误

你当前的preRegistration视图存在初始化问题:GET请求时不能用request.POST初始化表单,改成空表单即可:

from .forms import MyForm
from django.contrib import messages

def preRegistration(request):
    if request.method == 'GET':
        form = MyForm()  # GET请求初始化空表单
        return render(request, 'registration_form.html', {"form": form})
    if request.method == 'POST':
        form = MyForm(request.POST)
        studentId = request.POST.get('studentId')
        # 处理其他字段逻辑...
        if form.is_valid():
            Applicant.objects.create(studentID=studentId, ...)
            return render(request, 'login.html')
        else:
            messages.error(request, '验证码错误!')
            return render(request, 'registration.html', {"form": form})

2. 编写刷新验证码的后端视图

实现refreshCaptcha视图,生成新的验证码并返回其图片URL和密钥:

from django.http import JsonResponse
from captcha.models import CaptchaStore
from captcha.helpers import captcha_image_url

def refreshCaptcha(request):
    # 生成新的验证码密钥
    new_key = CaptchaStore.generate_key()
    # 获取对应验证码图片的URL
    image_url = captcha_image_url(new_key)
    # 返回JSON格式的结果
    return JsonResponse({'key': new_key, 'image_url': image_url})

记得在项目的urls.py中添加该视图的路由:

from django.urls import path
from . import views

urlpatterns = [
    path('pre-registration/', views.preRegistration, name='pre-registration'),
    path('refresh-captcha/', views.refreshCaptcha, name='refresh-captcha'),
]

3. 修改前端模板并添加JS逻辑

给刷新按钮和验证码容器添加标识,方便JS定位元素,然后编写点击刷新的逻辑:

<div><input type="text" name="studentId"></div>
<div><input type="text" name="Name"></div>
...
<div class="captcha-box">{{ form.captcha }}</div>
<button type="button" class="btn" id="refresh-captcha">刷新验证码</button>
<button type="submit" class="btn btn-primary">提交</button>

<script>
document.getElementById('refresh-captcha').addEventListener('click', function() {
    // 发送请求到刷新验证码的后端接口
    fetch('{% url "refresh-captcha" %}')
        .then(res => res.json())
        .then(data => {
            // 获取验证码图片和隐藏的密钥输入框
            const captchaImg = document.querySelector('.captcha-box img');
            const captchaKeyInput = document.querySelector('.captcha-box input[type="hidden"]');
            
            // 更新图片地址和密钥值
            captchaImg.src = data.image_url;
            captchaKeyInput.value = data.key;
        })
        .catch(err => console.log('刷新失败:', err));
});
</script>

逻辑说明

  • 后端通过CaptchaStore.generate_key()生成新的验证码密钥,captcha_image_url()生成对应图片的访问地址
  • 前端用fetch发起异步请求,拿到新的密钥和图片地址后,替换原有验证码的图片和隐藏字段(这个隐藏字段是django-simple-captcha自动生成的,用于存储验证码密钥)
  • 整个过程不会刷新页面,也不会影响表单内其他字段的已填内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 17:25:26