一、分页器

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. Vue3生命周期钩子函数深度解析:从源码到实战的万字指南

    一.Vue3生命周期革新特性 相较于Vue2,Vue3通过Composition API带来了更灵活的生命周期管理方式.通过onBeforeMount等函数注册钩子时,实际是通过injectHook方 ...

  2. AI+Web3:张三的未来机会地图

    热点风暴:ETHDenver 2025掀起热潮 滑动微信的那一刻,张三愣住了.热搜上,ETHDenver大会简直是技术圈的春晚.AI和Web3,这两个曾经高高在上的概念,突然变得触手可及.大会透露的一 ...

  3. Electron 客户端开机自启动

    app.setLoginItemSettings 与 auto-launch 对比分析 一.稳定性对比 1. app.setLoginItemSettings 优点:作为Electron官方API,有 ...

  4. 【Linux】3.4 用户管理

    用户管理 1. 基本用户管理 Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. 用户的账号一方面可以帮助 ...

  5. Armbian 安装与更换为国内软件源

    Armbian 是为 ARM 架构的单板计算机(如树莓派.NanoPi.Orange Pi 等)提供的开源镜像系统,它基于 Debian 或 Ubuntu 系统.在使用 Armbian 进行开发.调试 ...

  6. 深度优先及广度优先在Unity中的应用

    说明: 简单总结一下深度优先算法和广度优先算法在Unity中最直观和最多见的使用.这里我所举的例子是应用到Unity中3D 人物的全部骨骼关键的遍历,推广开就是能够对全部物体的层级关系进行简单的遍历. ...

  7. LinkedBlockingQueue的take方法底层源码

    一.LinkedBlockingQueue的take方法底层源码 LinkedBlockingQueue 的 take 方法是其核心方法之一,用于从队列头部移除并返回元素.如果队列为空,调用 take ...

  8. bat脚本之启动MySQL服务

    @echo off :: 获取管理员权限 %1 mshta vbscript:CreateObject("Shell.Application").ShellExecute(&quo ...

  9. git rebae -i

    这个命令大体作用就是对本地的commit进行修改,适用于以下情况: 本地历史排查修改 code review后,打回修改 详解 pick,只是意味着包括提交.重新进行命令时,重新安排pick命令的顺序 ...

  10. 聊聊SpringAI流式输出的底层实现?

    在 Spring AI 中,流式输出(Streaming Output)是一种逐步返回 AI 模型生成结果的技术,允许服务器将响应内容分批次实时传输给客户端,而不是等待全部内容生成完毕后再一次性返回. ...