一、分页器

1、分页器的好处

通过分页管理多条数据,可以美化界面并能提高查询效率

2、一般方式进行分页

def get_students(request):

    page = int(request.GET.get("page", 1))  # 获取页码

    per_page = int(request.GET.get("per_page", 10))  # 获取每页需要显示的数量

    students = Student.objects.all()[per_page*(page-1): page * per_page]   # 进行分页查询

    data = {
"students": students
} return render(request, 'students.html', context=data)

3、使用分页器

from django.core.paginator import Paginator

3.1、分页器对象

(1)、实例化分页器对象
paginator = Paginator(数据源,每页最多显示的条数)
(2)、属性

count 对象总数

num_pages 页面总数

page_range 页码列表,从1开始

(3)、方法

page(page_num) 返回一个page对象,page_num为页码(整数)

3.2、页面对象

具体的某一页,由分页器的Page方法获得。

(1)、属性和方法

page_num 当前页码

object_list 当前页的数据

has_next 是否有下一页

has_previous 是否有上一页

next_page_number 下一页页码

previous_page_number 上一页页码

len() 当前页数据的个数

4、常见错误

(1)、InvalidPage

  page()传递无效页码

(2)、PageNotAnInteger

  page()传递的不是整数

(3)、Empty

  page()传递的值有效,但是没有数据

5、实例

(1)、url

from django.urls import path

from myapp.views import show_students

app_name = 'myapp'

urlpatterns = [
path('showstu/<pagenum>/',show_students,name='students'),
]

(2)、view

from django.core.paginator import Paginator
from django.shortcuts import render from myapp.models import Student page_size = 3 #每页最多显示的条数 def show_students(request,pagenum): #pagenum是页码参数
students = Student.objects.all() #查询所有学生,返回QuerySet
paginator = Paginator(students,page_size) #实例化'分页器对象',传入容器和page_size
page = paginator.page(pagenum) #通过分页器对象返回Page,Page对象封装了某一页信息
page_range = paginator.page_range # 页码列表
return render(request,'students.html',locals())

(3)、html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生信息</title>
</head>
<body>
<table align="center" border="1">
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>成绩</th>
</tr>
{% for student in page %}
<tr>
<td>{{ student.id }}</td>
<td>{{ student.name }}</td>
<td>{{ student.age }}</td>
<td>{{ student.score }}</td>
</tr>
{% endfor %} </table>
<center>
<a href="{% url 'myapp:students' 1 %}">首页</a>
{% if page.has_previous %}
<a href="{% url 'myapp:students' page.previous_page_number %}">上一页</a>
{% else %}
<a href="javascript:alert('已经是首页了')">上一页</a>
{% endif %}
{% if page.has_next %}
<a href="{% url 'myapp:students' page.next_page_number %}">下一页</a>
{% else %}
<a href="javascript:alert('已经是末页了')">下一页</a>
{% endif %} <a href="{% url 'myapp:students' paginator.num_pages %}">末页</a> </center>
</body>
</html>

(4)、添加bootstrap样式

cdn:https://www.bootcdn.cn/

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/1.2.3/jquery.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.0/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.0/js/bootstrap.js"></script>
</head>
<body>
<table align="center" border="1">
<tr>
<th>学号</th>
<th>姓名</th>
<th>成绩</th>
</tr>
{% for student in page.object_list %}
<tr>
<td>{{ student.id }}</td>
<td>{{ student.name }}</td>
<td>{{ student.score }}</td>
</tr>
{% endfor %} </table>
<center>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page.has_previous %}
<li>
<a href="{% url 'myapp:students' page.previous_page_number %}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %} <li class="disabled">
<a href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% endif %} {% for page_index in page_range %}
{% ifequal page_index page.number %}
<li class="active"><a href="{% url 'myapp:students' page_index %}">{{ page_index }}</a></li>
{% else %}
<li><a href="{% url 'myapp:students' page_index %}">{{ page_index }}</a></li>
{% endifequal %} {% endfor %} {% if page.has_next %}
<li>
<a href="{% url 'myapp:students' page.next_page_number %}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% endif %} </ul>
</nav>
</center>
</body>
</html>

二、图片验证码

防止其它人恶意注册或访问攻击

1、手动实现验证码

(1)pillow

画布Image

  需要模式 RGB

  尺寸 (width, height)

  背景色 (10,20,30)

画笔ImageDraw

  绑定画布

  模式:RGB和ARGB

  封装了绘制的方法:test 绘制文本

           point 绘制点

           line 画线

           arch  圆弧形

字体ImageFront

   手动指定字体

(2)、绘制流程

指定可用背景颜色 

bg = (220, 220, 180)  #RGB颜色

初始化画布

image = Image.new(‘RGB’,(120,30),bg)

获取画布中画笔对象

draw = ImageDraw.Draw(image, 'RGB')

随机四位验证码并绘制

a、生成4位随机字符
def generate_code():
source = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM" code = "" for i in range(4):
code += random.choice(source) return code
b、创建字体
font = ImageFont.truetype(font='static/font/Fangz.ttf', size=25)
c、指定字体颜色
font_color = (random.randrange(255),
random.randrange(255),
random.randrange(255))
d、绘制内容
draw.text((x,y),’R’,font,fontcolor)
e、画干扰点
for i in range(10000):
fill = (random.randrange(255),
random.randrange(255),
random.randrange(255))
xy = (random.randrange(201), random.randrange(100))
imagedraw.point(xy=xy, fill=fill)

最后生成图片或图片对象,并返回响应。

2、和用户体系绑定

验证码真实数据需要持久化

session

cookie

3、动态刷新

浏览器缓存,根据url比对,

添加随机数,让url每次都发生变更

<img width="120" height="100%" src="/user/verifycode"
onclick="flushVerifyCode(this)"><br> function flushVerifyCode(img) {
img.src= '/user/verifycode?tm='+Math.random();
}

4、实例

(1)、view

import random
from io import BytesIO
from PIL import Image, ImageFont
from PIL.ImageDraw import Draw, ImageDraw def get_color():
return random.randrange(256) def generate_code():
source = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM" code = "" for i in range(4):
code += random.choice(source) return code def get_code(request): # 初始化画布,初始化画笔 mode = "RGB" size = (200, 100) red = get_color() green = get_color() blue = get_color() color_bg = (red, green, blue) image = Image.new(mode=mode, size=size, color=color_bg) imagedraw = ImageDraw(image, mode=mode) imagefont = ImageFont.truetype(settings.FONT_PATH, 100) verify_code = generate_code() request.session['verify_code'] = verify_code for i in range(4):
fill = (get_color(), get_color(), get_color())
imagedraw.text(xy=(50*i, 0), text=verify_code[i], font=imagefont, fill=fill) for i in range(10000):
fill = (get_color(), get_color(), get_color())
xy = (random.randrange(201), random.randrange(100))
imagedraw.point(xy=xy, fill=fill) fp = BytesIO() image.save(fp, "png") return HttpResponse(fp.getvalue(), content_type="image/png")

(2)、html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.11.1/jquery.js"></script> </head>
<body> <form action="{% url 'myapp:login' %}" method="post"> <span>用户名:</span> <input type="text" name="username" placeholder="精神精神"> <br>
<span>验证码:</span><input type="text" name="verify_code" placeholder="请输入下图中的验证码">
<br>
<img src="{% url 'myapp:get_code' %}">
{# <img src="#">#}
<br>
<button>精神一下</button>
</form>
</body>
</html> <script>
$(function () {
$("img").click(function () {
console.log("点到我了");
$(this).attr("src", "/myapp/get_code/?t=" + Math.random());
})
})
</script>

(3)、setting

FONT_PATH = os.path.join(BASE_DIR, 'static/fonts/ADOBEARABIC-BOLD.OTF')

Django中的分页器以及手绘验证码的更多相关文章

  1. 第二十五节:scrapy爬虫识别验证码(四)手绘验证码识别

    一.介绍 今天主要介绍的是微博客户端在登录时出现的四宫格手绘验证码,不多说直接看看验证码长成什么样.        二.思路 1.由于微博上的手绘验证码只有四个宫格,且每个宫格之间都有有向线段连接,所 ...

  2. django中的分页器组件

    目录 django的组件-分页器 引入分页器 分页器demo 创建数据库模型 url控制器 views视图函数 templates模板 为什么要用分页器 导入分页器 分页器优化1 分页器优化2 有多少 ...

  3. (31)django中的分页器

    book_list = models.Book.objects.all()    #查出指定表中的所有数据paginator = Paginator(book_list,2)    #实例化对象,传入 ...

  4. Django中使用极验Geetest滑动验证码

    一,环境部署 1.创建一个django测试项目 此处省略... 二,文档部署 1.下载安装python对应的SDK 使用命令从Github导入完整项目:git clone https://github ...

  5. UWP 手绘视频创作工具 “来画Pro” 技术分享系列

    开篇先来说一下我和来画的故事,以及写这篇文章的初衷. 今年年初时,我还在北京,在 Face++,做着人脸识别技术的 Windows 和 Android 端,做着人工智能终将实现世间所有美好的梦.这时的 ...

  6. UWP 手绘视频创作工具技术分享系列

    开篇先来说一下写这篇文章的初衷. 初到来画,通读了来画 UWP App 的代码,发现里面确实有很多比较高深的技术点,同时也是有很多问题的,扩展性,耦合,性能,功能等等.于是我们决定从头重构这个产品,做 ...

  7. UWP 手绘视频创作工具技术分享系列 - 文字的解析和绘制

    本篇作为技术分享系列的第二篇,详细讲一下文字的解析和绘制,这部分功能的研究和最终实现由团队共同完成,目前还在寻找更理想的实现方式. 首先看一下文字绘制在手绘视频中的应用场景 文字是手绘视频中很重要的表 ...

  8. Django中生成随机验证码(pillow模块的使用)

    Django中生成随机验证码 1.html中a标签的设置 <img src="/get_validcode_img/" alt=""> 2.view ...

  9. Django中验证码的登录

    需求概述 一般登录页面或者其他页面都需要验证码的功能,那在Django中如何实现呢? 这基本就需要用到第三方模块了:pillow 还需要两个文件,一个是字体文件:Monaco.ttf,另一个是一个模块 ...

  10. Django中图形验证码(django-simple-captcha)

    django-simple-captcha 在网站开发的登录页面中,经常会需要使用到图形验证码来验证.在Django中,django-simple-captcha库包提供了图形验证码的使用. 下面我们 ...

随机推荐

  1. Grafana导入 json 文件的 dashboard 错误 Templating Failed to upgrade legacy queries Datasource xxx not found

    前言 编辑或者修改后的 dashboard 保存为 json 文件,在其他环境导入使用,报错 Failed to upgrade legacy queries Datasource xxxxxxx w ...

  2. Ubuntu20.04搭建k8s v1.23.3版本集群

    前言 服务器统一版本 Ubuntu 20.04 搭建集群最少要两台服务器 每台服务器都需要 docker.环境配置.安装 kubeadm.kubelet 和 kubectl docker 安装 doc ...

  3. nginx 配置go服务反向代理

    nginx 配置 详细请看Nginx 极简教程 server { listen 80; server_name localhost; #charset koi8-r; # nginx访问活动日志 ac ...

  4. 关于能否用DeepSeek做危险的事情,DeepSeek本身给出了答案

    AI教父辛顿说DeepSeek允许本地部署的话可能会导致用户用DeepSeek来做一些危险的事情(https://t.cj.sina.com.cn/articles/view/7879923924/m ...

  5. JDK 24 发布,新特性解读!

    真快啊!Java 24 这两天已经正式发布啦!这是自 Java 21 以来的第三个非长期支持版本,和 Java 22.Java 23一样. 下一个长期支持版是 Java 25,预计今年 9 月份发布. ...

  6. 堆排序(标准版)(NB)

    博客地址:https://www.cnblogs.com/zylyehuo/ # _*_coding:utf-8_*_ import random def sift(li, low, high): # ...

  7. 团队小规模本地大模型服务平台搭建 - Ubuntu

    实现目标和考虑因素 部署一个支持多用户同时使用.多模型运行的离线局域网大模型服务器 需要考虑以下几个关键因素: 大模型的加载和管理.使用一个基础大模型,根据实战需要创建多个专用模型,模型管理方便可靠. ...

  8. Delphi Richedit代码语法加亮显示

    procedure CodeColors(Form : TForm;Style : String; RichE : TRichedit;InVisible : Boolean); const // s ...

  9. SearXNG私有化部署与Dify集成

    一.概述 SearXNG 是一个免费的互联网元搜索引擎,它聚合了来自各种搜索服务和数据库的结果,但摆脱了隐私追踪 -- 用户行为既不会被引擎跟踪也不会被分析. 功能特性 自托管,可以私有化部署 没有用 ...

  10. CentOS linux 安装openssl(openssl拒绝服务漏洞【CVE-2022-0778】解决)

    一.安装 1.下载相关openssl包 下载地址: https://www.openssl.org/source/ 2.将下载好的压缩包放到 /app/server/nginx 路径下(根据自己实际需 ...