在Django项目中封装分页类并使用分页类

一、分页的逻辑与处理规则

通过从数据库中提取数据的形式分析如何分页

queryset = models.PrettyNum.objects.all() # 提取数据库中该表中的所有数据

queryset = models.PrettyNum.objects.filter(id=1)[0:10] # 提取数据库中前十条数据


# 第1页
queryset = models.PrettyNum.objects.all()[0:10]

# 第2页
queryset = models.PrettyNum.objects.all()[10:20]

# 第3页
queryset = models.PrettyNum.objects.all()[20:30]
data = models.PrettyNum.objects.all().count()
data = models.PrettyNum.objects.filter(id=1).count()

分页的逻辑和处理规则

from django.forms import ModelForm
from django.shortcuts import render, HttpResponse, redirect
import app01.models
from app01 import models
from django.forms import ModelForm
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django.utils.safestring import mark_safe



def pretty_list(request):
    """靓号列表"""
    # 添加数据循环加入300条一样的数据
    # for i in range(300):
    #     models.PrettyNum.objects.create(mobile="18530123456", price=20, level=2, status=1)
    data_dict = {}
    search_data = request.GET.get('q', "")
    if search_data:
        data_dict["mobile__contains"] = search_data
    # res = models.PrettyNum.objects.filter(**data_dict)

    # 1.根据用户想要访问的页码,计算出起止位置
    page = int(request.GET.get("page", 1))
    page_size = 10 # 每页显示10条数据
    start = (page - 1) * page_size
    end = page * page_size

    # select *from 表 order by level desc;
    queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")[start:end]

    # 数据总条数
    total_count = models.PrettyNum.objects.filter(**data_dict).order_by("-level").count()
    # 总页码
    total_page_count, div = divmod(total_count, page_size)
    if div:
        total_page_count += 1
    # 计算出,显示当前页的前5页、后5页
    plus = 5
    if total_page_count <= 2 * plus+1:
        # 数据库中数量比较少,都没有达到11页
        start_page = 1
        end_page = total_page_count
    else:
        # 数据库中的数据比较多>11页
        # 当前页<5时(小极值)
        if page <= plus:
            start_page = 1
            end_page = 2 * plus + 1
        else:
            # 当前页>5
            # 当前页+5 > 总页面
            if (page + plus) > total_page_count:
                start_page = total_page_count - 2 * plus
                end_page = total_page_count
            else:
                start_page = page - plus
                end_page = page + plus

    # 页码
    page_str_list = []
    # 首页
    page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1))
    # 上一页
    if page > 1:
        prev = '<li><a href="?page={}">上一页</a></li>'.format(page - 1)
    else:
        prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
    page_str_list.append(prev)
    # 页面
    for i in range(start_page, end_page + 1):
        if i == page:
            ele = '<li class="active" ><a href="?page={}">{}</a></li>'.format(i, i)
        else:
            ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
        page_str_list.append(ele)
    # 下一页
    if page < total_page_count:
        prev = '<li><a href="?page={}">下一页</a></li>'.format(page + 1)
    else:
        prev = '<li><a href="?page={}">下一页</a></li>'.format(total_page_count)
    page_str_list.append(prev)
    # 尾页
    page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(total_page_count))
    search_string = """
            <li style="float: right;">
                <form method="get">
                    <div class="input-group" style="width:118px;border-radius: 0;">
                        <input type="text" name="page" class="form-control" placeholder="页码" style="border-radius: 0;">
                        <span class="input-group-btn">
                            <button class="btn btn-default" type="submit" style="color:#337AB7">跳转</button>
                        </span>
                    </div>
                </form>
            </li>
    """

    page_str_list.append(search_string)
    page_string = mark_safe("".join(page_str_list))
    return render(request, "pretty_list.html", {"queryset": queryset, "search_data": search_data, "page_string": page_string})

 在要分页的html中添加以下代码:

<ul class="pagination">
  {{ page_string }}
</ul>

二、封装分页类

 

在 app 目录下创建一个新文件夹 utils 文件夹

在 utils 目录下创建 pagination.py 文件( 写项目用【pagination.py】公共组件)。

"""
自定义的分页组件,以后如果想要使用这个分页组件,你需要做如下几件事:

在视图函数中(views.py):
from app01.utils.pagination import Pagination
def pretty_list(request):

    # 1.根据自己的情况去筛选自己的数据
    queryset = models.PrettyNum.objects.all()

    # 2.实例化分页对象
    page_object = Pagination(request, queryset)

    context = {
        "search_data": search_data,
        "queryset": page_object.page_queryset, # 分完页的数据
        "page_string": page_object.html(), # 生成页码
    }

    return render(request, "pretty_list.html", context)

在html页面中:
    {% for obj in queryset %}
        {{ obj.xxx }}
    {% endfor %}

    <ul class="pagination">
        {{ page_string }}
    </ul>

"""
from django.utils.safestring import mark_safe


class Pagination(object):

    def __init__(self, request, queryset, page_size=10, page_param="page", plus=5):
        """
        :param request: 请求的对象
        :param queryset: 符合条件的数据(根据这个数据给他进行分页处理)
        :param page_size: 每页显示多少条数据
        :param page_param: 在URL中传递的获取分页的参数,例如:/etty/list/?page=12
        :param plus: 显示当前页的前几页或后几页(页码)
        """

        from django.http.request import QueryDict
        import copy
        query_dict = copy.deepcopy(request.GET)
        query_dict._mutable = True
        self.query_dict = query_dict
        self.page_param = page_param
        page = request.GET.get(page_param, "1")
        if page.isdecimal():
            page = int(page)
        else:
            page = 1
        self.page = page
        self.page_size = page_size
        self.start = (page - 1) * page_size
        self.end = page * page_size

        self.page_queryset = queryset[self.start:self.end]

        # 数据总条数
        total_count = queryset.count()
        # 总页码
        total_page_count, div = divmod(total_count, page_size)
        if div:
            total_page_count += 1
        self.total_page_count = total_page_count
        self.plus = plus

    def html(self):
        # 计算出,显示当前页的前5页、后5页

        if self.total_page_count <= 2 * self.plus + 1:
            # 数据库中数量比较少,都没有达到11页
            start_page = 1
            end_page = self.total_page_count
        else:
            # 数据库中的数据比较多>11页
            # 当前页<5时(小极值)
            if self.page <= self.plus:
                start_page = 1
                end_page = 2 * self.plus + 1
            else:
                # 当前页>5
                # 当前页+5 > 总页面
                if (self.page + self.plus) > self.total_page_count:
                    start_page = self.total_page_count - 2 * self.plus
                    end_page = self.total_page_count
                else:
                    start_page = self.page - self.plus
                    end_page = self.page + self.plus

        # 页码
        page_str_list = []
        # 首页
        self.query_dict.setlist(self.page_param, [1])
        page_str_list.append('<li><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))
        # 上一页
        if self.page > 1:
            self.query_dict.setlist(self.page_param, [self.page - 1])
            prev = '<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [1])
            prev = '<li><a href="?page={}">上一页</a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(prev)
        # 页面
        for i in range(start_page, end_page + 1):
            self.query_dict.setlist(self.page_param, [i])
            if i == self.page:
                ele = '<li class="active" ><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            else:
                ele = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            page_str_list.append(ele)
        # 下一页
        if self.page < self.total_page_count:
            self.query_dict.setlist(self.page_param, [self.page + 1])
            prev = '<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [self.total_page_count])
            prev = '<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(prev)
        # 尾页
        self.query_dict.setlist(self.page_param, [self.total_page_count])
        page_str_list.append('<li><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))
        search_string = """
                    <li style="float: right;">
                        <form method="get">
                            <div class="input-group" style="width:118px;border-radius: 0;">
                                <input type="text" name="page" class="form-control" placeholder="页码" style="border-radius: 0;">
                                <span class="input-group-btn">
                                    <button class="btn btn-default" type="submit" style="color:#337AB7">跳转</button>
                                </span>
                            </div>
                        </form>
                    </li>
            """

        page_str_list.append(search_string)
        page_string = mark_safe("".join(page_str_list))
        return page_string
from app01.utils.pagination import Pagination

def depart_list(request):
    """部门列表"""
    # 去数据库中获取所有的部门名称
    queryset = models.Department.objects.all()
    page_object = Pagination(request, queryset, page_size=2)  # 每页显示几条(page_size=2)
    context = {
        "queryset": page_object.page_queryset,
        "page_string": page_object.html(),
    }
    # print(queryset)
    return render(request, "depart_list.html", context)
<ul class="pagination" style="position: absolute;transform: translate(50%);">
	{#    style="position: absolute;transform: translate(50%);" 居中设置 根据实际情况改动       #}
	{{ page_string }}
</ul>

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值