Django-simple-captcha实现图片和输入框的样式

django验证码的插件

一、安装

pip install django-simple-captcha

二、配置和安装

  1. settting.py

    • 在 INSTALLED_APPS ,添加 captcha

    • 在末尾增加 captcha 增加如下配置:

      CAPTCHA_IMAGE_SIZE = (120,50)  #图片大小
      CAPTCHA_BACKGROUND_COLOR = '#FFFFFF'
      CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge' # 采用随机字母的形式
      CAPTCHA_LENGTH = 4  # 4个字母的产长度
      CAPTCHA_TIMEOUT = 1 # 1分钟失效
      
  2. 执行数据库迁移:

    python manage.py makemigrations
    python manage.py migrate
    

三、在 form 引入验证码字段

  1. 可以直接创建登录的form表单类,在这个类中增加captcha的CaptchaField字段

    from captcha.fields import CaptchaField
    class LoginForm(forms.Form):
        username = forms.CharField(required=True,label="Username")
        password = forms.CharField(widget=forms.PasswordInput,
                                   required=True,label='Password')
        captcha = CaptchaField()
    
  2. 增加captcha的 url 配置,主要是两个地方,一个是生成图片的地址/captcha,另外一个是验证码验证的api接口:但是注意,一般把 生成图片的url写在全局的urls.py,把ajax_val写在自己的app下

        path('captcha/',include('captcha.urls')), # 这是验证码的url,写在项目目录下的urls.py
        path('ajax_val', views.ajax_val,name='ajax_val'),  #这是自己写的Ajax进行校验的
    

四、实现登录和验证码的views.py

  1. 主要是在views.py实现login和ajax_val
def login_view(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        # 验证表单
        if form.is_valid():
            u = form.cleaned_data.get('username')
            p = form.cleaned_data.get('password')
            if CustomUser.objects.filter(username=u).exists():
                user = authenticate(username=u,password=p)
                if user is not None:
                    login(request,user)
                    tips = '登录成功'
                    return HttpResponseRedirect(reverse('wms:index'))
                else:
                    tip = '账号密码错误,请重新输入'
            else:
                tips = '用户不存在,请注册'
    else:
        form = LoginForm()
    return render(request,'wms/login.html',locals())
  1. ajax接口,实现动态验证码验证

    def ajax_val(request):
        if request.is_ajax():
            # 用户输入的验证码结果
            r = request.GET['response']
            # 隐藏域的VALUE值
            h = request.GET['hashkey']
            # 去表中查看是否有对应的hashkey和r
            cs = CaptchaStore.objects.filter(hashkey=h,response=r)
            if cs:
                # 到这里说明找到了
                json_data = {'status':1}
            else:
                json_data = {'status':0}
            return JsonResponse(json_data)
        else:
            json_data = {'status':0}
            return JsonResponse(json_data)
    

    五、修改输出顺序和样式-我自己的亲测

    1 . 要实现的目标:

    image-20241211210709498

    y617的登录界面,css采用layui框架,左侧输入框,右侧图片,而且输入框前面还有一个小图标。

    2. 出现问题

    captcha默认是图片-隐藏字段-输入框这个排列。且没办法把图片和输入框分开。

    3. 解决过程

    (1) settings添加2个配置项

    一个是在INSTALLED_APPS 增加:'django.forms' ,另外一个是增加一句:

    FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
    

    (2)自定义的form中添加代码

    #创建一个自定义的input类
    class CustomCaptchaTextInput(CaptchaTextInput):
        template_name = "my_captcha.html"
    

    然后在实际表单中,增加captcha这个字段:

    class MyAuthenticationForm(AuthenticationForm):
        captcha = CaptchaField(widget=CustomCaptchaTextInput(attrs={"autofocus": True,'value': '','class':'layui-input', 'lay-verify':'required|captcha','placeholder': '验证码','lay-reqtext': '请填写验证码','lay-affix': 'clear',
                                                            }))
    

    这样就能实现这个字段出来就带样式了;

    (3) 编写自定义的my_captcha.html文件

    按照上面的类中定义的模板名称,新建这个文件,然后放在项目的templates下。

    {% load i18n %}
    {% load myfilter %}
    {% spaceless %}
    
    <div class="layui-form-item">
        <div class="layui-row">
            <div class="layui-col-xs7">
                <div class="layui-input-wrap">
                    <div class="layui-input-prefix">
                        <i class="layui-icon layui-icon-vercode"></i>
                    </div>
                    {% for widget in widget.subwidgets|reversed %}{% include widget.template_name %}{% endfor %}
                    <div class="layui-input-affix layui-input-suffix layui-hide"><i class="layui-icon layui-icon-clear"></i>
                    </div>
                </div>
            </div>
            <div class="layui-col-xs5">
                <div style="margin-left: 10px;">
                    <img class="captcha-img" id="captcha-img" src="{{ image }}" style="cursor: pointer"  onclick="">
                </div>
            </div>
        </div>
        <div class="layui-row"><span class="alert-danger">{{ form.captcha.errors.0 }}</span></div>
    </div>
    {% endspaceless %}
    

(4)编写反序输出的过滤器函数myfilter

上面html中 {% load myfilter %},这是一个自定义的过滤器,要放在某个app目录下的templatetags目录:

# myapp/templatetags/myfilter.py:
from django import template
register = template.Library()

@register.filter
def reversed(value):
    return value[::-1]

(5)注意增加上点击刷新图片的js代码

<script>
<!-- 验证码的刷新ajax -->    
$('.captcha').click(function () {
    $.getJSON("/captcha/refresh/", function (result) {
        $('.captcha').attr('src', result['image_url']);
        $('#id_captcha_0').val(result['key'])
    });
});
</script>

到这实现了全部功能。

posted @   saromman  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示