一、安装captcha

pip install django-simple-captcha

二、注册captcha

在 settings.py 的 INATALLED_APPS 中注册captcha。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'login',
    'captcha',
]

执行migrate命令,生成captcha数据库表,保存验证码。

python manage.py migrate

三、添加路由

在根目录的urls.py文件中添加captcha对应的url:

from django.contrib import admin
from django.urls import path
from django.urls import include
from login import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('captcha/', include('captcha.urls'))   # 增加这一行
    path('captcha/refresh/', include('captcha.urls'))   # 点击验证码,使用ajax刷新
]

四、修改forms.py文件

from django import forms
from captcha.fields import CaptchaField

class UserForm(forms.Form):
    username = forms.CharField(label="用户名", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': "Username",'autofocus': ''}))
    password = forms.CharField(label="密码", max_length=256, widget=forms.PasswordInput(attrs={'class': 'form-control',  'placeholder': "Password"}))
    captcha = CaptchaField(label='验证码')

五、修改login.html

添加{{ form.captcha }}和ajax刷新验证码功能。

{% load static %}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <title>登录</title>
    <link rel="stylesheet" type="text/css" href="https://cdn.staticfile.org/semantic-ui/2.4.1/semantic.min.css">
    <link rel="stylesheet" type="text/css" href="{% static 'css/semantic.custom.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
    <script src="/static/js/md5.js"></script>
    <script src="/static/js/sha1.js"></script>
    <script src="/static/js/funcbase64.js"></script>
    <script src="/static/js/aes.js"></script>

</head>
<body id="v-account-body">
<div class="ui middle aligned center aligned grid">
    <div class="column v-account">
        <img src="{% static 'img/registerLogo.png' %}" class="image">
        <h2 class="ui teal image header">

        </h2>
        <form class="ui large form" novalidate method="post" action="{% url 'users:login' %}"
              enctype="multipart/form-data" onsubmit='return checkForm()'>
            {% csrf_token %}
            <div class="ui stacked segment">
                <div class="field">
                    <div class="ui left icon input">
                        <i class="user icon"></i>
                        {{form.username}}
                    </div>
                </div>
                <div class="field">
                    <div class="ui left icon input">
                        <i class="lock icon"></i>
                        {{form.password}}
                    </div>
                </div>
                <div class="field">

                    <div class="ui left icon input">
                        <i class="shield icon"></i>
                        {{form.captcha}}
                    </div>
                </div>
                <input type="hidden" name="next" value="{{ next }}"/>
                <button class="ui fluid large teal submit button" type="submit">登录</button>
            </div>

            {% include "base/form_errors.html" %}

        </form>

        <div class="ui message">
                还没有账号?<a href="{% url 'users:signup' %}">注册</a>
        </div>
    </div>
</div>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script src="/static/bootstrap-4.3.1-dist/js/bootstrap.min.js"></script>
<script type="text/javascript">

//验证码动态刷新实现
$('.captcha').click(function () {
    $.getJSON("/captcha/refresh/", function (result) {
        $('.captcha').attr('src', result['image_url']);
        $('#id_captcha_0').val(result['key'])
    });
});

</script>
</body>

</html>

注意在写动态刷新验证码之前,需要先引入jquery-1.11.3.min.js 和 bootstrap.min.js

 

这样写完之后会出现 验证码在左边,输入框在右边,不符合正常审美,So:

在settings.py中添加下面一句:

# 验证码样式
CAPTCHA_OUTPUT_FORMAT = u'%(text_field)s %(hidden_field)s %(image)s'

OK!!!