Django基础9(Django中分页)

Django中自定义分页

准备工作:

1、html准备

1、引入bootstrap框架
2、引入jQuery

2、数据库准备

from django.db import models

# Create your models here.


class User(models.Model):
    user = models.CharField(max_length=32)
models.py

3、在django项目根目录下简历一个自定义py文件(作用插入300条数据)

"""
创建时间 : 2018/05/08
版本号 : V1
文档名 : myscript.py
编辑人 : he_wm
作 用 : 批量插入300条数据
"""

import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "paging_assembly.settings")
    import django
    django.setup()
    # 创建300条数据
    from app01 import models
    ret = []
    for i in range(300):
        obj = models.User(user="hewm{}".format(i))
        ret.append(obj)
    # 批量创建(只提交一次)
    # 列表推导式
    # ret = [models.User(user="hewm{}".format(i))for i in range(300)]
    models.User.objects.bulk_create(ret)
myscript.py

源码区:

1、templates/look.html

<!--
创建时间 : 2018/05/08
版本号 : V1
文档名 : look.html
编辑人 : he_wm
作 用 : 显示数据
-->

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>look</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3-3-7/css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">

    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3 class="panel-title">数据表单</h3>
        </div>
        <div class="panel-body">
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>#</th>
                    <th>ID</th>
                    <th>姓名</th>
                </tr>
                </thead>
                <tbody>
                {% for user in user_list %}
                    <tr>
                        <td>{{ forloop.counter }}</td>
                        <td>{{ user.id }}</td>
                        <td>{{ user.user }}</td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
            <div class="bs-example" data-example-id="disabled-active-pagination">
                <nav aria-label="...">
                    <ul class="pagination">
                        {{ page_html|safe }}
                    </ul>
                </nav>
            </div>
        </div>
    </div>
</div>
<script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
<script src="{% static 'bootstrap-3-3-7/js/bootstrap.min.js' %}"></script>
</body>
</html>
look.html

2、分页显示函数(views\looks())

from django.shortcuts import render
from .models import *


# Create your views here.


def looks(request):
    # 查询数据库中所有数据
    data = User.objects.all()
    # 每页显示条数配置  目前为10条
    per_page = 10
    # 获取数据条数
    data_num = data.count()
    # 获取需要多少页来展示数据
    page_num, more = divmod(data_num, per_page)
    if more:
        page_num += 1
    # 获取页码,如未获取默认取第一页
    current_page = request.GET.get("page", 1)
    # 防止传进的为非数字数值(默认返回第一页)
    try:
        current_page = int(current_page)
    except:
        current_page = 1
    # 如果传过来的页码是个小于1的数返回第一页
    if current_page <= 0:
        current_page = 1
    # 如果传过来的页码是大于最大页码数返回最后一页
    elif current_page > page_num:
        current_page = page_num
    # 页面最多显示11个页码
    max_show = 7
    half_show = max_show // 2
    # 如果当前页码小于中间页码值
    if current_page - half_show <= 1:
        # 页码设置最小页码为1页,最大为最多显示页码
        page_start = 1
        page_end = max_show
    # 如果右面超出页码值范围
    elif current_page + half_show >= page_num:
        # 最后一页为最大页码数
        page_end = page_num
        # 另一边界为最大页码减去一页显示的页码数
        page_start = page_num - max_show
    else:
        # 中间页码左边显示多少
        page_start = current_page - half_show
        # 中间页码右面显示多少
        page_end = current_page + half_show
    # 确定数据在哪开始切
    data_start = (current_page - 1) * per_page
    # 确定数据切到哪
    data_end = current_page * per_page
    # 对数据进行切片
    user_list = data[data_start:data_end]
    # user_list = User.objects.all()
    # 生成页码
    l = []
    # 加一个首页
    l.append('<li><a href="/looks/?page=1">首页<span class="sr-only"></span></a></li>')
    # 加个上一页
    if current_page == 1:
        l.append(
            '<li class="disabled"><a href="/looks/?page={}" aria-label="Previous"><span aria-hidden="true">«</span></a></li>'.format(
                current_page - 1))
    else:
        l.append(
            '<li><a href="/looks/?page={}" aria-label="Previous"><span aria-hidden="true">«</span></a></li>'.format(
                current_page - 1))
    # 循环生成所有的页码html的代码存储(后期修改成动态配置显示多少条页码)
    for i in range(page_start, page_end + 1):
        if i == current_page:
            tmp = '<li class = "active"><a href="/looks/?page={}">{}<span class="sr-only"></span></a></li>'.format(i, i)
        else:
            tmp = '<li><a href="/looks/?page={}">{}<span class="sr-only"></span></a></li>'.format(i, i)
        l.append(tmp)
    # 加个下一页
    print(current_page)
    print(page_num)
    if current_page == page_num:
        l.append(
            '<li class="disabled"><a href="/looks/?page={}" aria-label="Previous"><span aria-hidden="true">»</span></a></li>'.format(
                current_page + 1))
    else:
        l.append(
            '<li><a href="/looks/?page={}" aria-label="Previous"><span aria-hidden="true">»</span></a></li>'.format(
                current_page + 1))
    # 加一个尾页
    l.append('<li><a href="/looks/?page={}">尾页<span class="sr-only"></span></a></li>'.format(page_num))

    #     以空格分隔
    page_html = "".join(l)
    return render(request, "look.html", locals())
looks逻辑函数

封装成类

# """
# 创建时间 : 2018/05/08
# 版本号 : V1
# 文档名 : my_page.py
# 编辑人 : he_wm
# 作 用 : 自定义分页组件
# 源存储位置 : D:\pycharm\python\paging_assembly\utils\my_page.py
# 修改及增加功能记录 :
#     修改时间 :
#         1、
#         2、
#     增加功能时间 :
#         1、
#         2、
# """


class Pagination(object):

    def __init__(self, data_num, current_page, url_prefix, per_page=10, max_show=11):
        """
        初始化
        :param data_num: 数据总数
        :param current_page: 当前页
        :param url_prefix: 生成页码链接前缀
        :param per_page: 每页显示多少条数据
        :param max_show: 页面最多显示多少个页码
        """
        self.data_num = data_num
        self.per_page = per_page
        self.max_show = max_show
        self.url_prefix = url_prefix
        # 获取需要多少页来展示数据
        self.page_num, more = divmod(data_num, per_page)
        if more:
            self.page_num += 1
        # 防止传进的为非数字数值(默认返回第一页)
        try:
            self.current_page = int(current_page)
        except:
            self.current_page = 1
        # 如果传过来的页码是个小于1的数返回第一页
        if self.current_page <= 0:
            self.current_page = 1
        # 如果传过来的页码是大于最大页码数返回最后一页
        elif self.current_page > self.page_num:
            self.current_page = self.page_num
        # 计算页码数的一半
        self.half_show = max_show // 2

        # 如果当前页码小于中间页码值
        if self.current_page - self.half_show <= 1:
            # 页码设置最小页码为1页,最大为最多显示页码
            self.page_start = 1
            self.page_end = self.max_show
        # 如果右面超出页码值范围
        elif self.current_page + self.half_show >= self.page_num:
            # 最后一页为最大页码数
            self.page_end = self.page_num
            # 另一边界为最大页码减去一页显示的页码数
            self.page_start = self.page_num - self.max_show
        else:
            # 中间页码左边显示多少
            self.page_start = self.current_page - self.half_show
            # 中间页码右面显示多少
            self.page_end = self.current_page + self.half_show

    # 确定数据从哪开始切方法
    @property
    def start(self):
        # 确定数据在哪开始切
        return (self.current_page - 1) * self.per_page

    # 确定数据切到哪方法
    @property
    def end(self):
        # 确定数据切到哪
        return self.current_page * self.per_page

    def page_html(self):
        # 生成页码
        l = []
        # 加一个首页
        l.append('<li><a href="{}?page=1">首页<span class="sr-only"></span></a></li>'.format(self.url_prefix))
        # 加个上一页
        if self.current_page == 1:
            l.append(
                '<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>'.format(
                    self.current_page))
        else:
            l.append(
                '<li><a href="{}?page={}" aria-label="Previous"><span aria-hidden="true">«</span></a></li>'.format(
                    self.url_prefix, self.current_page - 1))
        # 循环生成所有的页码html的代码存储(后期修改成动态配置显示多少条页码)
        for i in range(self.page_start, self.page_end + 1):
            if i == self.current_page:
                tmp = '<li class = "active"><a href="{}?page={}">{}<span class="sr-only"></span></a></li>'.format(
                    self.url_prefix, i, i)
            else:
                tmp = '<li><a href="{}?page={}">{}<span class="sr-only"></span></a></li>'.format(self.url_prefix, i, i)
            l.append(tmp)
        # 加个下一页
        if self.current_page == self.page_num:
            l.append(
                '<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">»</span></a></li>'.format(
                    self.current_page))
        else:
            l.append(
                '<li><a href="{}?page={}" aria-label="Previous"><span aria-hidden="true">»</span></a></li>'.format(
                    self.url_prefix, self.current_page + 1))
        # 加一个尾页
        l.append('<li><a href="{}?page={}">尾页<span class="sr-only"></span></a></li>'.format(self.url_prefix, self.page_num))

        #     以空格分隔
        return "".join(l)

调用方法

from django.shortcuts import render
from .models import *


# Create your views here.


def looks(request):
    # 引入分页组件模块
    from utils import my_page
    # # 查询数据库中所有数据
    data = User.objects.all()
    # 获取数据条数
    data_num = data.count()
    # # 获取页码,如未获取默认取第一页
    current_page = request.GET.get("page", 1)
    # 传参
    obj = my_page.Pagination(data_num, current_page, "/looks/")
    # 对数据进行切片
    user_list = data[obj.start:obj.end]
    # 获取传到模板中分页的HTML代码
    page_html = obj.page_html()
    return render(request, "look.html", locals())

 

posted @ 2018-05-08 22:42  争-渡  阅读(135)  评论(0)    收藏  举报