DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • Django

    • 框架引入
    • 基本配置
    • 单表记录CURD
    • 路由和视图层
    • 模版层
    • ORM查询
    • ORM字段
    • Ajax+layer
    • 自定义分页器
      • 批量插入数据
      • 分页(简单版)
      • 分页类(优化版)
    • cookie与session
    • 中间件和csrf
    • Auth认证模块
    • ORM复习
    • 测试Demo
  • 第一次学drf

  • 第二次学drf

  • 温故知新

  • flask

  • 后端
  • Django
DC
2023-10-14
目录

自定义分页器

参考文档: https://www.cnblogs.com/Dominic-Ji/articles/12035722.html

# 批量插入数据

bulk_create
★ models.Book.objects.bulk_create(book)

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=32)


### --- ### --- ### --- ### 


from django.test import TestCase

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ajax.settings")
    import django

    django.setup()

    from app01 import models

    # -- 一条条的添加10万条数据很慢很慢!!
    # for i in range(100000):
    #     models.Book.objects.create(title="第%s本书" % i)

    # -- ★ 批量添加10万条数据!
    #    ★★★★★与上面相比,只需要执行一次sql语句/只用操作一次数据库!!
    book = []
    for i in range(10000):
        book_obj = models.Book(title="第%s本书" % i)
        book.append(book_obj)
    models.Book.objects.bulk_create(book)
    
    # -- Ps:清空表中的数据  models.Book.objects.all().delete()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 分页(简单版)

首先要明确:
1> get请求是可以携带参数的, 所以前端朝后端发送查看数据的同时可以携带一个参数告诉后端我们想看第几页的数据;
2> queryset对象是支持索引取值和切片操作的,但是不支持负数索引!!

分页四要素: 当前页、总数量、每页条数、总页数

准备数据: 批量的往book表中插入 103条 数据!!

views.py

from django.shortcuts import render

from app01 import models


def index(request):
    all_count = models.Book.objects.all().count()  # -- 总数据有多少条
    per_page = 10  # -- 每页展示多少条数据
    # -- 计算出一共多少页 all_page
    #    使用python的内置方法divmod
    integer, mod = divmod(all_count, per_page)  # -- all_count / per_page => (整数,余数)
    if mod: # -- 有余数,则总页数加1
        all_page = integer + 1
    else:
        all_page = integer

    # -- current_page 当前第几页
    #    获取用户想访问的页码,如果没有,默认展示第一页
    current_page = request.GET.get('page', 1)
    try:  # -- 由于后端接受到的前端数据是字符串类型,所以我们这里做类型转换处理加异常捕获
        current_page = int(current_page)
    except Exception as e:
        current_page = 1
    # -- 需要对总数据进行切片操作,即需要确定切片起始位置和终止位置
    start = (current_page - 1) * per_page  # -- 当前页是从数据库的第几条数据开始
    end = current_page * per_page  # -- 当前页是到数据库的第几条数据结束(不包含尾数据)
    # -- 切片是顾头不顾尾的!
    #    当前实验数据是103条,共11页,最后一页的切片是[100,110],由于切片的特性,只取到103条,不会报错!
    book_list = models.Book.objects.all()[start:end]

    html = ""
    for i in range(1, all_page + 1):
        if i == current_page:
            # -- class="active" 添加高亮
            html += '<li class="active"><a href="?page=%s" >%s</a></li>' % (i, i)
        else:
            html += '<li><a href="?page=%s" >%s</a></li>' % (i, i)

    return render(request, 'index.html', locals())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <title>Title</title>
</head>
<body>
<br>
{% for book in book_list %}
    <p style="margin-left: 100px">
        {{ book.title }}
    </p>
{% endfor %}

{# 直接cv拷贝bootstrap的分页组件相关代码 #}
<nav aria-label="Page navigation">
    <ul class="pagination">
        <li>
            <a href="#" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        {{ html|safe }}
        <li>
            <a href="#" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
    </ul>
</nav>

</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

扩展: 上面代码默认每页展示10条数据, 有个需求, 让根据用户的选择设定每页展示的条数..
解决 -- 在前端有个下拉框,让用户选择条数,将这个条数像当前页一样通过url参数传到后端.. ?page=1&per_page=10


# 分页类(优化版)

添加了上一页、下一页、首页、尾页等功能.

Ps: 自己写分页器可以使用该代码,在公司里,有现成的..

因为自定义的分页器代码属于第三方的,我们在根目录下创建 名为lib 或者 utils 的文件夹进行存放!!

utils.mypage.py

class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=10, pager_count=8):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数
        :return page_html_list: 前端分页栏代码(前端是需要使用Bootstrapt的!)
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page
        self.all_count = all_count
        self.per_page_num = per_page_num

        # -- 总页码
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # -- 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # -- 总页码  > 11
        else:
            # -- 当前页如果<=页面上最多显示11/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # -- 当前页大于5
            else:
                # -- 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # -- 添加前面的nav和ul标签
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        # -- 首页
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)
        # -- 上一页
        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
        page_html_list.append(prev_page)
        # -- 当前页
        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)
        # -- 下一页
        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)
        # -- 尾页
        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # -- 添加结束标签
        page_html_list.append('''</nav></ul>''')

        return ''.join(page_html_list)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

前端分页栏点击的效果如下: (这里默认显示的页码为8个!)

views.py

from django.shortcuts import render

from app01 import models
from utils.mypage import Pagination


def index(request):
    book_count = models.Book.objects.all().count()  # -- 总数据有多少条
    current_page = request.GET.get('page', 1)  # -- 当前第几页

    obj = Pagination(current_page, book_count)
    book_list = models.Book.objects.all()[obj.start:obj.end]
    page_html = obj.page_html()

    return render(request, 'index.html', locals())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <title>Title</title>
</head>
<body>
<br>
{% for book in book_list %}
    <p style="margin-left: 100px">
        {{ book.title }}
    </p>
{% endfor %}

{{ page_html|safe }}

</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Ps: Django的from组件进行表单校验参考链接 https://www.cnblogs.com/Dominic-Ji/p/9240365.html

Ajax+layer
cookie与session

← Ajax+layer cookie与session→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式