1-Django - 实现分页

about

django3.2 + python3.9 + mysql5.7 + boostrap3

这里演示在Django中,结合boostrap3来自定义分页器,以及简单的应用示例。

代码示例

urls.py

from django.contrib import admin
from django.urls import path
from api.views import index, create_data

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', index),   # 展示分页
    path('create_data/', create_data, name='create_data'),  # 最开始访问这个路由创建一些数据
]

models.py

from django.db import models


class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='书籍名称')
    price = models.FloatField(verbose_name='书籍价格')
    pub_date = models.DateField(verbose_name='出版日期')
    publish = models.CharField(max_length=32, verbose_name='出版社名称')

    # 当打印book对象时,通过 __str__ 的返回更友好的结果
    def __str__(self):
        return self.title

views.py

mport datetime
from django.shortcuts import render, HttpResponse
from django.utils.safestring import mark_safe
from api import models


# 这个类中的代码可以不用动
class MyPagenation(object):
    """ 自定义分页器 """
    def __init__(self,page_num,total_count,per_page_num,page_num_show,base_url):

        self.per_page_num = per_page_num  # 每页显示10条
        # 页面生成页码的数量
        self.page_num_show = page_num_show  # 7      4 5 6 7 8
        self.base_url = base_url  # 7      4 5 6 7 8
        try:
            page_num = int(page_num)
        except Exception:
            page_num = 1
        self.page_num = page_num

        shang, yu = divmod(total_count, self.per_page_num)  # shang:商    yu:余数
        # 总页码数
        if yu:
            page_num_count = shang + 1
        else:
            page_num_count = shang
        self.page_num_count = page_num_count
        if page_num <= 0:
            page_num = 1
        elif page_num > page_num_count:
            page_num = page_num_count

        # 3 4 5 6 7    4 5 6 7 8 9 10
        half_show = self.page_num_show // 2  # 2
        if page_num - half_show <= 0:
            start_page_num = 1
            end_page_num = self.page_num_show + 1  # 9

        elif page_num + half_show > page_num_count:
            start_page_num = page_num_count - self.page_num_show + 1  # 26 - 5 = 21
            end_page_num = page_num_count + 1  # 27  [21,22,23,24,25,26]
        else:
            start_page_num = page_num - half_show  # 4  1
            end_page_num = page_num + half_show + 1  # 9  6

        self.start_page_num = start_page_num
        self.end_page_num = end_page_num

    @property
    def start_data_num(self):
        return (self.page_num - 1) * self.per_page_num

    @property
    def end_data_num(self):
        return self.page_num * self.per_page_num

    def page_hmtl(self):
        page_num_range = range(self.start_page_num, self.end_page_num)
        page_html = ''
        page_pre_html = '<nav aria-label="Page navigation"><ul class="pagination">'
        page_html += page_pre_html
        first_page_html = '<li><a href="{1}?page={0}" aria-label="Previous"><span aria-hidden="true">首页</span></a></li>'.format(1, self.base_url)
        page_html += first_page_html
        if self.page_num <= 1:
            pre_page = '<li class="disabled"><a href="javascript:void(0)" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(self.page_num - 1)
        else:
            pre_page = '<li><a href="{1}?page={0}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(self.page_num - 1,self.base_url)

        page_html += pre_page
        for i in page_num_range:
            if i == self.page_num:
                page_html += '<li class="active"><a href="{1}?page={0}">{0}</a></li>'.format(i,self.base_url)
            else:
                page_html += '<li><a href="{1}?page={0}">{0}</a></li>'.format(i,self.base_url)
        if self.page_num >= self.page_num_count:
            page_next_html = '<li class="disabled"><a href="javascript:void(0)" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                self.page_num + 1)
        else:
            page_next_html = '<li><a href="{1}?page={0}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                self.page_num + 1,self.base_url)
        page_html += page_next_html
        last_page_html = '<li><a href="{1}?page={0}" aria-label="Previous"><span aria-hidden="true">尾页</span></a></li>'.format(
            self.page_num_count, self.base_url)
        page_html += last_page_html
        end_html = '</ul></nav>'
        page_html += end_html

        return mark_safe(page_html)




def index(request):
    """ 分页示例 """
    # http://127.0.0.1:8004/index/?page=24
    # 通过get请求获取page参数的值,也就是要查看的页码
    page_num = request.GET.get('page')
    base_url = request.path  #访问的路径

    # 数据的总条数
    customer_count = models.Book.objects.all().count()
    
    # 这两个值可以随便调整
    per_page_num = 10  #每页显示多少条数据
    page_num_show = 10  #显示的页码数
    
    # 完事调用自定义分页器拿到分页器对象
    page_obj = MyPagenation(page_num,customer_count,per_page_num,page_num_show,base_url)
    # 结合boostrap的分页样式,拿到分页的html字符串,后续在页面中直接渲染即可
    page_html = page_obj.page_hmtl()
    # 对数据库中的数据,根据根据分页器对象切片获取当前页的模型类对象的queryset
    book_obj = models.Book.objects.all().reverse()[page_obj.start_data_num:page_obj.end_data_num]
    # 然后通过模板语法进行展示分页
    return render(request,'index.html',{'book_obj':book_obj,'page_html':page_html})


def create_data(request): 
    """ 初始化一些数据,用于后续分页展示用"""
    tmp_list = [
        models.Book(
                title='红楼梦{}'.format(i),
                price=9.9 + i,
                pub_date=datetime.datetime.now(),
                publish='机械工业出版社'
            )
        for i in range(1, 996)]
    models.Book.objects.bulk_create(tmp_list)
    return HttpResponse("创建数据完毕")

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<h1>分页效果展示</h1>
<!-- 循环当前页的数据 -->
<table class="table table-striped table-hover">
    <thead>
    <tr>
        <th>书籍名称</th>
        <th>书籍价格</th>
        <th>出版日期</th>
        <th>出版社</th>
    </tr>
    </thead>
    <tbody>
    {% for book in book_obj %}
        <tr>
            <td>{{ book.title }}</td>
            <td>{{ book.price }}</td>
            <td>{{ book.pub_date }}</td>
            <td>{{ book.publish }}</td>
        </tr>
    {% endfor %}

    </tbody>
</table>
<div>
    <!-- 分页器在此渲染 -->
    {{ page_html }}
</div>
</body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
</html>

效果展示

posted @ 2022-10-30 11:48  听雨危楼  阅读(91)  评论(0)    收藏  举报