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

前言:

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

   在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, includeurlpatterns = [#省略其他配置path('captcha/', include('captcha.urls')),
]

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

# comment/forms.py
from captcha.fields import CaptchaFieldclass 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 timezoneclass 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, VerifyCaptchaurlpatterns = [# 省略其他配置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.xdnf.cn/news/147020.html

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

相关文章

[Python数据可视化]探讨数据可视化的实际应用:三个案例分析

数据可视化是理解复杂数据集的重要工具&#xff0c;通过图形化的方法&#xff0c;可以直观地展示信息、趋势和模式。本文将深入探讨三个实际案例&#xff0c;包括健康数据分析、销售趋势分析、城市交通流量分析。每个案例将提供假设数据、详细注释的代码及分析结果。 案例 1: …

【每日刷题】Day128

【每日刷题】Day128 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 606. 根据二叉树创建字符串 - 力扣&#xff08;LeetCode&#xff09; 2. LCR 194. 二叉树的最近公…

Spring在不同类型之间也能相互拷贝?

场景还原 日常开发中&#xff0c;我们会定义非常多的实体&#xff0c;例如VO、DTO等&#xff0c;在涉及实体类的相互转换时&#xff0c;常使用Spring提供的BeanUtils.copyProperties&#xff0c;该类虽好&#xff0c;可不能贪用。 这不在使用过程中就遇到一个大坑&#xff0c…

逻辑分析仪看波形方法

一、串口波形讲解 异步串行数据的一般格式是&#xff1a;起始位数据位停止位&#xff0c;其中起始位1 位&#xff0c;数据位可以是5、6、7、8位&#xff0c;停止位可以是1、1.5、2位。 对于正逻辑的TTL电平&#xff0c; a.起始位是一个值为0的位&#xff0c;低电平&#xff…

leetcode练习 二叉树的最大深度

给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3提示&#xff1a; 树中节点的数量在 [0, 104] 区间内。-100 …

【图像检索】基于Gabor特征的图像检索,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于Gabor特征的图像检索&#xff0c;用matlab实现。 一、案例背景和算法介绍 这次博…

排序----快速排序(快排)(递归版)

首先讲一下单趟的思路&#xff1a; 在这一块数据中&#xff0c;记录第一个元素为key&#xff0c;然后设置L和R两个指针&#xff0c;L找比key处的元素大的&#xff0c;R找比key处元素小的&#xff0c;找到了就交换这两个位置的元素。当两个指针相遇时&#xff0c;若相遇点的元素…

20240921在友善之臂的NanoPC-T6开发板上确认宸芯的数传模块CX6602N的AT命令

console:/dev # cat ttyUSB1 & console:/dev # echo AT > ttyUSB1 20240921在友善之臂的NanoPC-T6开发板上确认宸芯的数传模块CX6602N的AT命令 2024/9/21 21:03 【必须】Android12/Linux&#xff08;Buildroot&#xff09;都必须要&#xff01; 4、【Android12默认打开U…

https的连接过程

根证书: 内置在操作系统和浏览器中,可手动添加,下级是中间证书或服务器证书,只有当中间证书或服务器证书关联到已存在的根证书时,中间证书或服务器证书才视为有效 中间证书: 位于根证书和服务器证书之间,他们之间也可以没有中间证书,作用是对根证书增加一个下级,方便管理,由根…

GAMES101(作业4~5)

作业四 题目&#xff1a; 由 4 个控制点表示的 Bzier 曲线&#xff0c; bezier&#xff1a;该函数实现绘制 Bzier 曲线的功能。它使用一个控制点序列和一个 OpenCV&#xff1a;&#xff1a;Mat 对象作为输入&#xff0c;没有返回值。它会使 t 在 0 到 1 的范围内进 行迭代&a…

【Linux】进程地址空间和进程调度队列

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/qinjh_/category_12625432.html 目录 问题现象 进程地址空间 进一步理解 地址空间 Linux2.6内核进程调度队列 …

RecyclerView的notifyDataSetChanged和notifyItemRemoved之间的区别

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 RecyclerView 提供了多种方法来通知适配器&#xff08;Adapter&#xff09;数据集发生变化&#xff0c;其中 notifyDataSetChanged() 和 notify…

数据库系统基础概述

文章目录 前言一、数据库基础概念 1.数据库系统的组成2.数据模型3.数据库的体系结构二、MySQL数据库 1.了解MySQL2.MySQL的特性3.MySQL的应用场景总结 前言 MySQL数据库是一款完全免费的产品&#xff0c;用户可以直接从网上下载使用&#xff0c;不用花费任何费用。这点对于初学…

proteus仿真学习(1)

一&#xff0c;创建工程 一般选择默认模式&#xff0c;不配置pcb文件 可以选用芯片型号也可以不选 不选则从零开始布局&#xff0c;没有初始最小系统。选用则有初始最小系统以及基础的main函数 本次学习使用从零开始&#xff0c;不配置固件 二&#xff0c;上手软件 1.在元件…

【AcWing】875. 快速幂

#include<iostream> using namespace std; typedef long long LL;LL qmi(int a,int b,int p){LL res1%p;//%p是为了p1的时候&#xff0c;余数是0while(b){if(b&1) resres*a%p;//位数是1的b>>1;aa*(LL)a%p;//a*a再modp是为了防止溢出}return res; }int main(){i…

【动态规划】(三)动态规划——完全背包

动态规划——完全背包 完全背包理论基础零钱兑换Ⅱ组合总和Ⅳ爬楼梯&#xff08;进阶版&#xff09;零钱兑换完全平方数单词拆分背包问题总结 完全背包理论基础 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品…

零食店小程序发展客户转化运营

零食店、折扣店近些年市场中跑出了不少区域性、多地化的品牌&#xff0c;直营及加盟模式&#xff0c;还有各种超市、商场、街边小店等&#xff0c;零食基本没有年龄群体限制&#xff0c;又属于常消费品&#xff0c;线上线下生意都可以进行发展。 线下客户到店&#xff0c;线上…

链表数据结构

链表可以解决顺序表的缺点 我们今天简单引用下链表 这边是代码讲解 头文件 #pragma once #include<stdio.h> #include<iostream> #include<string.h> #include<stdlib.h> using namespace std; typedef struct student {union {int data;int len;};s…

【计网】从零开始掌握序列化与反序列化 --- 基础知识储备与程序重构

从零开始掌握序列化与反序列化 1 初识序列化与反序列化2 再谈Tcp协议3 程序重构3.1 Socket类3.2 回调函数设计3.3 最终的Tcp服务器类 1 初识序列化与反序列化 在刚学习计算机网络时&#xff0c;我们谈到过网络协议栈&#xff0c;其中最上层的就是应用层&#xff0c;那么这个应…

Rosetta 一:手把手教你用Linux安装Rosetta(全网最简洁)

文章目录 1. Rosetta 介绍2.下载2. Rosetta 安装3. 验证安装 1. Rosetta 介绍 很久很久之前就对Rosetta有所耳闻&#xff0c;有一篇文章叫做denovo protein design&#xff0c;说的就是用rosetta来设计蛋白质。 rosetta是david baker团队设计的软件&#xff0c;早期只是一个蛋…