django项目中通用的分页组件

文章目录

分页组件

应用分页组件,需要以下两个步骤:

  1. 视图函数中:(先获取queryset,将request和queryset传入分页组件对象中,得到生成的html标签)

    python 复制代码
    def customer_list(request):
        # 所有数据
        queryset = models.Customer.objects.filter(active=1).select_related('level')
    
        pager = Pagination(request, queryset)
        context = {
            "queryset": queryset[pager.start:pager.end],
            "pager_string": obj.html()
        }
        return render(request, 'customer_list.html', context)
  2. 在页面上:(直接引用即可)

    html 复制代码
    {% for row in queryset %}
        {{row.id}}
    {% endfor %}
    
    <ul class="pagination">
        {{ pager_string }}
    </ul>

pager组件代码

python 复制代码
import copy
from django.utils.safestring import mark_safe


class Pagination(object):
    """ 分页 """

    def __init__(self, request, query_set, per_page_count=10):
        """
        :param request: 需要用request对象中的GET中的数据进行校验和处理
        :param query_set: 查询数据库得到的查询集
        :param per_page_count: 每页显示几条数据
        """
        # 防止分页操作对后续的使用request.GET有影响
        self.query_dict = copy.deepcopy(request.GET)

        # 将self.query_dict._mutable设置为True:表示query_dict可修改,默认为False
        self.query_dict._mutable = True

        # 拿到总数据据数
        self.query_set = query_set
        total_count = query_set.count()
        self.total_count = total_count

        # 计算出总共有多少页面
        self.total_page, div = divmod(total_count, per_page_count)
        if div:
            self.total_page += 1

        # 对url中的请求参数进行校验处理,决定显示那一页
        page = request.GET.get('page')
        if not page:
            page = 1
        else:
            if not page.isdecimal():
                page = 1
            else:
                page = int(page)
                if page <= 0:
                    page = 1
                else:
                    if page > self.total_page:
                        page = self.total_page
        self.page = page

        # 每页数据条数
        self.per_page_count = per_page_count

        # 页面第一条数据
        self.start = (page - 1) * per_page_count
        # 页面最后一条数据
        self.end = page * per_page_count

    def html(self):
        """
        :return: 生成的当前页面的分页栏html
        """
        pager_list = []
        if not self.total_page:
            return ""

        # 求出生成的分页栏html显示的页面范围
        if self.total_page <= 11:
            # 总页码小于11
            start_page = 1
            end_page = self.total_page
        else:
            # 总页码比较多
            # 判断当前页 <=6: 1~11
            if self.page <= 6:
                start_page = 1
                end_page = 11
            else:
                if (self.page + 5) > self.total_page:
                    # 显示最后10页
                    start_page = self.total_page - 10
                    end_page = self.total_page
                else:
                    # 显示前后5页
                    start_page = self.page - 5
                    end_page = self.page + 5

        # 添加url中的参数,而不是替换:?&age=19&name=123&page=1
        # 首页
        self.query_dict.setlist('page', [1])
        pager_list.append('<li><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))

        # 上一页
        if self.page > 1:
            self.query_dict.setlist('page', [self.page - 1])
            pager_list.append('<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode()))

        # 当前页+前后5页
        for i in range(start_page, end_page + 1):
            self.query_dict.setlist('page', [i])
            if i == self.page:
                item = '<li class="active"><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            else:
                item = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            pager_list.append(item)

        # 下一页
        if self.page < self.total_page:
            self.query_dict.setlist('page', [self.page + 1])
            pager_list.append('<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode()))

        # 尾页
        self.query_dict.setlist('page', [self.total_page])
        pager_list.append('<li><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))

        pager_list.append('<li class="disabled"><a>数据{}条{}页</a></li>'.format(self.total_count, self.total_page))
        pager_string = mark_safe("".join(pager_list))
        return pager_string


  def queryset(self):
      """
      :return: 生成的当前页面的展示数据
      """
      if self.total_count:
          return self.query_set[self.start:self.end]
      return self.query_set

可能用到django框架中QueryDict知识点,可以看看Django框架中的:QueryDict(处理url参数)
若有错误与不足请指出,关注DPT一起进步吧!!!

相关推荐
测试员周周4 小时前
【AI测试智能体】为什么传统测试方法对智能体失效?
开发语言·人工智能·python·功能测试·测试工具·单元测试·测试用例
dfdfadffa4 小时前
如何用模块化方案组织一个可扩展的前端组件库项目
jvm·数据库·python
2301_812539674 小时前
SQL中如何高效实现分组数据的批量更新_利用窗口函数与JOIN
jvm·数据库·python
RSTJ_16254 小时前
PYTHON+AI LLM DAY THREETY-NINE
开发语言·人工智能·python
2501_901200534 小时前
如何实现SQL存储过程存储过程参数标准化_统一命名规范
jvm·数据库·python
运气好好的5 小时前
Golang怎么用embed嵌入SQL文件_Golang如何将SQL迁移文件嵌入Go程序统一管理【技巧】
jvm·数据库·python
AC赳赳老秦5 小时前
政企内网落地:OpenClaw 离线环境深度适配方案,无外网场景下本地化模型对接与全功能使用
java·大数据·运维·python·自动化·deepseek·openclaw
星越华夏5 小时前
python 将相对路径变成绝对路径
python
l1t6 小时前
mingw和Linux中的gcc和llvm编译器编译的pocketpy执行同一个python脚本的不同效果
linux·运维·python
砚底藏山河6 小时前
股票数据API接口:如何获取股票历历史分时KDJ数据
java·python·maven