一、分页器

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. [Qt基础-06] QButtonGroup

    QButtonGroup 本文主要根据QT官方帮助文档以及日常使用,简单的介绍一下QButtonGroup的功能以及基本使用 文章目录 QButtonGroup 简介 信号和槽 简介 有的时候,我们会 ...

  2. jquery给一个li标签添加和去掉class属性

    $("li").addClass('xxx').siblings().removeClass("xxx");

  3. nginx服务和uwsgi服务如何设置开机自启动

    上次学到了在云服务器下如何部署Django项目,用到了nginx服务和uwsgi服务,需要手工启动这2个服务的命令. 现在考虑如何设置开机自启动,为什么要这样考虑?因为服务器万一出问题,意外重启了,那 ...

  4. 「2024 年度技术精华盘点」IvorySQL & PostgreSQL 技术干货全解析!

    2024 年,IvorySQL 公众号持续输出高质量技术内容,涵盖 PostgreSQL 核心技术解析 和 IvorySQL 创新实践 两大方向.无论您是数据库领域的初学者,还是经验丰富的开发者,这些 ...

  5. MySQL-事务中的一致性读和锁定读的具体原理

    前言 上一篇文章MySQL-InnoDB行锁中,提到过一致性锁定读和一致性非锁定读,这篇文章会详细分析一下在事务中时,具体是如何实现一致性的. 一致性读原理 start transaction和beg ...

  6. .NET Core & ConsoleApp & appsettings.json

    准备 Visual Studio 2017 .NET Core 2.1 新建控制台应用(.NET Core) 默认的 Program.cs // Program.cs using System; na ...

  7. 如何定位 Druid & HikariCP 连接池的连接泄漏问题?

    背景 最近碰到一个 case,一个 Java 应用无法获取新的数据库连接,日志中出现了以下错误: com.alibaba.druid.pool.GetConnectionTimeoutExceptio ...

  8. Codeforces Round 954 (Div. 3)

    A. X Axis 1.既然要求每个点到a到距离之和最小,不妨让点a为3个点中的中间点,也就是先对三个数从小到大排序,然后输出首尾数减中间值的绝对值之和即可 #include <bits/std ...

  9. 经过几天的努力Biwen.AutoClassGen终于实现了DTO复杂属性的生成

    前言 距写上一篇 https://www.cnblogs.com/vipwan/p/18535459 生成DTO已经有一段时间了, 最初没有考虑复杂二级属性嵌套的实现,而是直接使用排除使用自定义的方式 ...

  10. 匿名内部类、lambda匿名函数表达式

    a.匿名内部类的定义格式: 接口名称 对象名 = new 接口名称(){ //覆盖重写所有抽象方法 }: 一. /** * lambda匿名函数的使用 * Lambda省去面向对象的条条框框,格式由3 ...