Django学习实战之评论验证码功能(附A)

news2024/9/22 13:54:36

前言:

   对于具有评论功能的博客来说,无论是否为知名博客,都会被恶意广告关注,上线没几天就会有人开始通过程序灌入广告评论,因此针对所有有用户输入的页面,验证码是必需品。

   在Django系统中使用验证码非常简单,因为有足够多的库供你选择,只要到djangositepackages网站搜索下就能看到:https://djangopackages.org/grids/g/captcha/

一、使用 django-simple-captcha

   要实现一个验证码,最简单的方式就是找一个使用量最大的库,或者GitHub上star数最多、最活跃的项目。只需要根据它的使用说明配置即可,比如我们将要用到的django-simple-captcha。

   第一步安装:

pip install django-simple-captchao

   第二步是配置 INSTALLED_APPS,修改settings.py:

INSTALLED_APPS = [
    'typeidea',
    'blog.apps.BlogConfig',
    'config.apps.ConfigConfig',
    'comment.apps.CommentConfig',
    'captcha',
	#省略其他配置
]

   第三步是配置urls.py:

# typeidea/urls.py
from django.urls import path, re_path, include

urlpatterns = [
	#省略其他配置
    path('captcha/', include('captcha.urls')),
]

   第四步是配置comment/forms.py:

# comment/forms.py
from captcha.fields import CaptchaField

class CommentForm(forms.ModelForm):
	# 省略其他代码
    captcha = CaptchaField()

   第五步是创建表:

 python manage.py migrate

   最后得到的验证码示例页面如下图所示:

在这里插入图片描述

二、配置验证码的几个要素

   如果仅仅是使用的话,那么只需要经过上面5个步骤就好了,方便、简单、快捷。但是如果老板要求你来根据自己的业务实现验证码的话,那么怎么做呢?如果你没有梳理清楚验证码的实现逻辑,基本上不可能自己来实现一套验证机制。

   我们梳理一下django-simple-captcha的实现逻辑,有这么几个要素:

  • 用户端验证码的唯一标识;
  • 在图片URL中通过唯一标识获取到对应的图片;
  • 后端存储已经生成过的验证码及标识;
  • 通过用户端的标识以及用户输入的验证码来判断是否存在这条记录。

   在整个过程中,你会觉得跟用户名和密码验证很相似,只是密码是实时生成到图片中的。

三、配置Ajax校验验证码

   理解了原理之后,要修改为Ajax验证的方式就很容易了。我们只需要实现通过接口拿到验证码标识以及验证码,然后判断数据库中是否存在即可。下面我们直接基于这个插件来改造。

   现在开发接口。在comment/views.py中增加如下代码:

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


class VerifyCaptcha(View):
    def get(self, request):
        captcha_id = CaptchaStore.generate_key()
        return JsonResponse({
            'captcha_id': captcha_id,
            'image_src': captcha_image_url(captcha_id),
        })

    def post(self, request):
        captcha_id = request.POST.get('captcha_id')
        captcha = request.POST.get('captcha', '')
        captcha = captcha.lower()

        try:
            CaptchaStore.objects.get(response=captcha, hashkey=captcha_id, expiration__gt=timezone.now()).delete()
        except CaptchaStore.DoesNotExist:
            return JsonResponse({'msg': '验证码错误'}, status=400)

        return JsonResponse({})
    

   在View里面我们完成了两件事:在get中生成图片验证码,在post中校验验证码以及清理掉校验通过的验证码。

   接下来,配置templates/comment/block.html,修改form位置的定义,并在下面新增script代码:

<hr/>
<div class="comment">
    <form id="comment_form" class="form-group" action="/comment/" method="POST">
        {% csrf_token %}
        <input name="target" type="hidden" value="{{ target }}"/>
        {{ comment_form }}
        <div id="captcha_section"></div>
        <input id="verify" type="button" value="写好了!"/>
        <input id="submit" type="submit" style="display:None" value="写好了!"/>
    </form>


    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
        $(document).ready(function(){
            var $form = $('.form-group');
            function init_captcha(){
                $.getJSON("{% url 'verify_captcha' %}", function(data){
                    $('#captcha_section').html(
                        '<img src="' + data.image_src + '" id="captcha_id" data-id="'+ data.captcha_id +'"/>' +
                        '<input id="captcha"/>'
                    );
                })
            }
            $( document ).on("click", '#captcha_id', init_captcha);

            $('#verify').on('click', function(){
                var captcha = $('#captcha').val();
                if (!captcha){
                    alert('验证码不能为空');
                    return;
                }
                $.ajax({
                    url: "{% url 'verify_captcha' %}",
                    method: 'POST',
                    data: {
                        'captcha_id': $('#captcha_id').data('id'),
                        'captcha': captcha,
                        'csrfmiddlewaretoken': '{{ csrf_token }}',
                    },
                    success: function(){
                        $('#submit').click();
                        setTimeout(init_captcha, 500);
                    },
                    error: function(res, data){
                        alert(res.responseJSON.msg);
                        return false;
                    }
                });
            });

            init_captcha();
        });
    </script>

    <!-- 评论列表 -->
    <ul class="list-group">
        {% for comment in comment_list %}
        <li class="list-group-item">
            <div class="nickname">
                <a href="{{ comment.website }}">{{ comment.nickname }}</a> <span>{{ comment.created_time }}</span>
            </div>
            <div class="comment-content">
                {% autoescape off %}
                {{ comment.content }}
                {% endautoescape %}
            </div>
        </li>
        {% endfor %}
    </ul>
</div>

   修改urls.py配置:

# typeidea/urls.py
from comment.views import CommentView, VerifyCaptcha

urlpatterns = [
	# 省略其他配置
    path('captcha/', include('captcha.urls')),
    path('verify_captcha/', VerifyCaptcha.as_view(), name='verify_captcha'),
]

   在上面的代码中,comment/forms.py中关于验证码部分的配置可以去掉了。

总结

   当我们使用一个新组件时,需要尽可能理解它的运行原理,这样我们在必要时可以很方便地对其进行定制,甚至根据这套原理来自行实现。

参考资料

django-simple-captcha文档:
http://django-simple-captcha.readthedocs.io/en/latest/

链接:

项目开源代码GitHub:https://github.com/1273055646/typeidea/tree/A-simple-captcha

Django学习实战篇一(适合略有基础的新手小白学习)(从0开发项目)

Django学习实战篇二(适合略有基础的新手小白学习)(从0开发项目)

Django学习实战篇三(适合略有基础的新手小白学习)(从0开发项目)

Django学习实战篇四(适合略有基础的新手小白学习)(从0开发项目)

Django学习实战篇五(适合略有基础的新手小白学习)(从0开发项目)

Django学习实战篇六(适合略有基础的新手小白学习)(从0开发项目)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2155206.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【面经】查找中常见的树数据结构

查找中常见的树数据结构 一、二叉排序&#xff08;搜索、查找&#xff09;树&#xff08;BST&#xff0c;Binary Search Tree&#xff09;&#xff08;1&#xff09;二叉排序树的查找、插入和删除过程&#xff08;2&#xff09;叉树排序树的缺陷&#xff08;3&#xff09;二叉排…

深度学习02-pytorch-04-张量的运算函数

在 PyTorch 中&#xff0c;张量&#xff08;tensor&#xff09;运算是核心操作之一&#xff0c;PyTorch 提供了丰富的函数来进行张量运算&#xff0c;包括数学运算、线性代数、索引操作等。以下是常见的张量运算函数及其用途&#xff1a; 1. 基本数学运算 加法运算&#xff1a…

【TypeScript入坑】TypeScript 的复杂类型「Interface 接口、class类、Enum枚举、Generics泛型、类型断言」

TypeScript入坑 Interface 接口简介接口合并TS 强校验Interface 里支持方法的写入class 类应用接口接口之间互相继承接口定义函数interface 与 type 的异同小案例 class 类类的定义与继承类的访问类型构造器 constructor静态属性&#xff0c;Setter 和 Getter做个小案例抽象类 …

Tomcat中BIO和NIO的区别(Tomcat)

BIO Tomcat中BIO的模型和理论很简单&#xff0c;例图如下 1.Acceptor线程死循环阻塞接收客户端的打过来的socket请求 2.接收到请求之后打包成一个SocketProcessor&#xff08;Runnable&#xff09;&#xff0c;扔到线程池中读取/写入数据 参数配置 1.Acceptor默认线程是1&#…

Day06微信小程序微信登录

微信小程序微信登录 1. 第一&#xff1a;小程序要先发给后端code(只能用一次)&#xff0c; 2. 后端要结合数据发给&#xff08;用get的方式&#xff09; https://api.weixin.qq.com/sns/jscode2session 数据&#xff1a; appidstring小程序的appIdsecretstring小程序的app…

华为为什么要做三折叠屏手机?

前些天我做了一条视频&#xff0c;关于讲华W的新的三折叠屏手机。我说我有点失望&#xff0c;结果引起了华W的同事的一些关注。于是&#xff0c;华W几位高管都跑过来&#xff0c;跟我解释为什么会出现这样的一个状态。 我才知道&#xff0c;这款手机他们其实是亏着钱在卖的。因…

【大模型实战篇】关于Bert的一些实操回顾以及clip-as-service的介绍

最近在整理之前的一些实践工作&#xff0c;一方面是为了笔记记录&#xff0c;另一方面也是自己做一些温故知新&#xff0c;或许对于理解一些现在大模型工作也有助益。 1. 基于bert模型实现中文语句的embedding编码 首先是基于bert模型实现中文语句的embedding编码&#xff0c;…

使用库函数点亮一个LED灯

软件设计 STM32Gpio的介绍 如果想让LED0点亮&#xff0c;那么R12就要是高电平&#xff0c;LED0就要是低电平&#xff0c;也就是PF9就是低电平 F407系统主频要工作在168MHZ F103的话是工作在72mhz F429的话就180MHZ 接着我们就要使能Gpio的时钟&#xff0c;使能之后对GPIO相关…

ES7 -- ES13

1. ES7 – 2016 1. 数组的includes方法 数组中是否包含某个元素&#xff0c;返回值为boolean let arr [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; arr.includes(5); // true2. ** 幂次方 let res 2 ** 3; // 82. ES8 --2017 1. 字符串补全 基本使用 let str 123;str.padStart…

Django 请求配置

http请求配置 请求流程 urls.py配置 from first_app import viewsurlpatterns [path(admin/, admin.site.urls),path(test/,views.first_test), ] views.py配置 from django.shortcuts import render,HttpResponse# Create your views here. def first_test(request):prin…

Kubernetes 安装网络插件flannel报错Init:ImagePullBackOff,flannel下载镜像报错问题解决

Kubernetes1.28安装网络插件flannel&#xff0c;报错Init:ImagePullBackOff &#xff0c;flannel安装下载镜像失败 问题 1.安装flannel kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml 2.flannel报错信息 执行查看安装…

Flutter 约束布局

配置插件依赖 设置组件大小 通过属性 childConstraints 实现 分别设置 约束布局一 和 约束布局二 大大小为:160 和 200 点击查看代码文件 class SummaryPageState extends State<SummaryPage1> {ConstraintId constraintId_1 = ConstraintId(ConstraintId_1);Constrain…

【GUI设计】基于Matlab的图像处理GUI系统(1),用matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于Matlab的图像处理GUI系统&#xff0c;用matlab实现。 本次内容主要分为两部分&a…

专题七_分治_快排_归并_算法专题详细总结

目录 分治 一、分治思想的概念 二、分治思想的步骤 1. 颜⾊分类&#xff08;medium&#xff09; 解析&#xff1a; 2. 快速排序&#xff08;medium&#xff09; 解析&#xff1a; 总结&#xff1a; 3. 快速选择算法&#xff08;medium&#xff09; 解析&#xff1a; …

【BurpSuite】Cross-site scripting (XSS 学徒部分:1-9)

&#x1f3d8;️个人主页&#xff1a; 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞&#x1f44d;收藏&#x1f497;支持一下哦 【BurpSuite】Cross-site scripting (XSS 学徒部分:1-9&#xff09; 实验一 Lab: Reflected XSS into HTML context with nothing…

maven手动导入本地仓库

maven手动导入本地仓库 1.在maven仓库下载对应的依赖 一定要把jar包下载到maven仓库的bin下 2.找到自己仓库的maven仓库下的bin目录cmd进去 在cmd窗口中输入以下命令&#xff1a;&#xff08;这里根据你的groupId、artifactId、version修改即可&#xff09; <!-- https:…

乱弹篇(53)丹桂未飘香

今天是2024年“秋分”节气&#xff0c;也是第7个中国“农民丰收节”&#xff0c;本“人民体验官”推广人民日报官方微博文化产品《文化中国行看丰收之美》。 截图&#xff1a;来源“人民体验官”推广平台 人民微博说&#xff1a;“春华秋实&#xff0c;岁物丰成。”又说&#…

dhtmlxGantt 甘特图 一行展示多条任务类型

效果如图: 后台拿到数据 处理之后如图: 含义: 如上图所示, 如果一行需要展示多个 需要给父数据的那条添加render:split属性, 子数据的parent为父数据的Id即可 切记 父数据的id 别为0 为0 时 会出现错乱 因为有些小伙伴提出分段展示的数据结构还是有点问题,下面展示一个完整…

机器人时代的“触觉革命”:一块小传感器如何颠覆你的认知?

你是否曾经想过,机器人也能像人类一样有“触觉”?不再是简单的机械操作,而是具备真正的感知能力,能够学会精细的任务。今天我想和你聊聊一种让机器人“长出触觉”的技术:一种小巧的触觉传感器,它的名字叫“AnySkin”。别看它小,它的潜力可一点都不小,或许能彻底改变我们…

Windows下如何定时执行自定义任务

目录 一.前言二.设置定时自动执行自定义任务 一.前言 本文环境是Windows11系统。 有时候我们希望能够在Windows下定时自动执行自定义任务&#xff0c;比如检测数据库服务的状态。那在Windows下怎么定时自动执行自定义任务&#xff0c;这篇文章介绍一种方法。 二.设置定时自动…