Django中的分页器以及手绘验证码

一、分页器

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‘)

原文地址:https://www.cnblogs.com/huiyichanmian/p/12219858.html

时间: 2024-11-13 06:53:10

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

UI设计培训中所需要的手绘能力

一.漫画 主要不是绘画能力,更重分镜头,叙事能力,脚本编写能力,很多画的不好,但依然存活很多年的漫画还真不少,甚至可以证明,绘画能力的底线可以很低. 二.游戏原画 虽然工作内容是画画,但游戏世界观多数是架空世界观,历史及文明的视觉搭建.所以对历史符号,架空世界观,产品类型,研发流程实现等行业知识更重要. 三.影视 跟游戏差不多,但是你设计出来的东西都能实现.场景,道具,服装,你对施工,材料,拍摄效果,后期等相关知识得有足够了解.那些看起来都是画画的工作,其实绘画只是表达手段.是最最基础的一个职业

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

今年年初时,我还在北京,在 Face++,做着人脸识别技术的 Windows 和 Android 端,做着人工智能终将实现世间所有美好的梦.这时的我已经离开 UWP,甚至 C# 很久了,写着 C++ 和 Java,当时真的没想过会再次回到 UWP 的阵营,直到 4 月份的时候,一次很偶然的机会,我的一位微软的朋友,也是 Face++的老朋友找到我询问我在 Face++ 的工作近况,本以为只是很久没联系之后的简单交流,直到他提到:在深圳,有一家叫做 "来画" 创业公司,做手绘视频工具和平

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

开篇先来说一下写这篇文章的初衷. 初到来画,通读了来画 UWP App 的代码,发现里面确实有很多比较高深的技术点,同时也是有很多问题的,扩展性,耦合,性能,功能等等.于是我们决定从头重构这个产品,做一个全新的 “来画Pro” 出来,历经三个月的世间,这个产品终于正式上架. (做个小广告,在 Windows 应用商店搜索 “来画Pro” 就可以找到,目前公司定位为收费应用,但是有一个月试用期,如果大家感兴趣,可以跟我要免费代码.这里是 IT之家的报道:https://www.ithome.com

【美术之家】手绘中透视的原理、应用及其练习方法,要收藏的哦

了解透视原理.是在熟练掌握线条的基础上能否准确绘制线稿的一个至关重要的环节.透视原理一一我们在进行手绘图绘制时,是根据空间尺寸在二维平面进行三维空间表达在绘制过程中,我们假想眼球与需要绘制的物体之间有一平面存在.并将平面后的物体运用透视法则投射到平面之上,从而形成该物体在图面上的图像如下面俯视图所示,视点为我们所处的位置,图面为我们与物体间的假想平面,图面后的物体为我们需要表达的三维形态. 第一阶段: 练习的时候还没有建立很强的透视消失感,应借助辅助线找对消失点,并且掌握在任何角度下都能熟练地表

Visio中手绘图形的填充

由于工作需要,现需用Visio绘制一个类似于DNA的螺旋图,为了使图片看起来更富有立体感,所以背面需要填充浅灰色,但由于是自己画的图形,并不能填充颜色,在网上查了很多资料也没有找到一个彻底的解决办法,不过倒是给我提供了一些思路,废话不多说了,现在我就详细说一下Visio中手绘图形的填充. 以手绘正方形的填充为例,注意是手绘,不是用Visio提供的正方形! Step1:用线条画出4条等长直线段 Step2:点击指针工具下面的"连接线",然后将光标移动至线条的顶端使其出现绿色的对其确认标志

手绘在工业设计中的重要位置

手绘对于一个优秀的设计师来说十分重要,它可以在短时间内将设计师的创意表达出来,一个好的设计师应该善于运用手绘来表达自己的设计理念.下面我们听听设计师李培新为我们介绍手绘在工业设计中的重要性. 手绘的作用 一个好的手绘表达是一个优秀设计的开始.当然不是说好的手绘图就是漂亮的手绘预想图,有时侯手绘可能是简单笨拙的笔触,但也能将自己的设计理念表达的淋漓尽致.好的手绘是将设计师的创意想法很快表达出来的一种方式. 好的手绘可以完整的表达出设计师的理念,而不是简单的效果图.作为在校的大学生,学好手绘很关键,

django 的分页器Paginator ,从django中导入类

先创建表,然后生成批量数据. 在models文件里 from django.db import models # Create your models here. class Book(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5,decimal_places=2) 然后执行python manage.py makemigrations   ,pytho

Django中生成随机验证码

Django中生成随机验证码 1.html中a标签的设置 1 <img src="/get_validcode_img/" alt=""> 2.views中的get2.views中的getvalidcode_img设置 导入文件 1 import json 2 import os 3 import random 4 from django.contrib import auth 5 from django.shortcuts import render,

Django自定制插件之【随机验证码】

前言 网站登录的时候我们常常会看到随机的验证码需要输入后台验证,如图: 现在我们来实现在Django中通过自定制插件来实现随机验证 check_code.py 基于PIL生成一个带验证码的图片和验证码,生成验证码图片需要Monaco.ttf字体(重要),可按自己要求更改check_code中的字体和字体文件位置 #!/usr/bin/env python # -*- coding:utf-8 -*- import random from PIL import Image, ImageDraw,