美文网首页
在 Django 中实现分页

在 Django 中实现分页

作者: Svon_Book | 来源:发表于2022-11-13 15:21 被阅读0次

    借助 Django 自带的 Paginator工具,实现类似B站的分页效果

    image.png

    伪码实现

    # views.py
    def view_func(request):
        接收 page 页参数
        result = Paginate(待分页对象, page, 每页元素数量)
        return render(...,{'result': result})
    
    class Pagination():
        验证 page 是否合理
        if 空页面 or 非法参数:
            raise Http404
    
        def items(self):
        返回分页后的对象
    
        def html_string(self):
        返回 html 文本,便于前端渲染
    
    <!--index.html-->
    {% for r in result.items %}
        输入分页元素
    {% endfor %}
    {% result.html_string %}
    

    1. page 参数验证

    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    class Paginate(object):
        def __init__(self, queryset, page, per_page=10):
            """
            :param queryset: 需要分页的对象集合
            :param page: 获取指定页数的对象集合,例如2/20
            :param per_page: 每页对象元素数量,默认10
            """
            self.django_paginator_obj = Paginator(queryset, per_page)
            try:
                self.current_page = self.django_paginator_obj.validate_number(page)
            except EmptyPage:
                raise Http404('该页无内容')
            except PageNotAnInteger:
                raise Http404('页码格式无效')
            self.current_page_items = self.django_paginator_obj.get_page(self.current_page)
    
    

    2. 返回分页后的对象

    class Paginate(object):
        ...
        def items(self):
            """
            按给定的 page 返回分页后的对象
    
            :return: QuerySet
            """
            return self.current_page_items.object_list
    

    3. 返回HTML 文本标记

    3.1 返回后的 HTML 标记格式如下

    借助 Bootstrap 样式实现:


    image.png

    3.2 三种页数情况的处理方法

    image.png

    3.3 关键代码

    class Paginate(object):
        ...
        def page_html_string(self):
            """
            :return: html element
            """
            start = end = 0
            # 处理总页不过5的情况
            if self.django_paginator_obj.num_pages <= 5:
                start = 1
                end = self.django_paginator_obj.num_pages
            else:
                # 处理 “初始页” 极值的情况
                if self.current_page - 2 <= 1:
                    start = 1
                    end = 5
                # 处理 “最后页” 极值的情况
                elif self.current_page + 2 >= self.django_paginator_obj.num_pages:
                    start = self.django_paginator_obj.num_pages - 5 + 1
                    end = self.django_paginator_obj.num_pages
                else:
                # 处理常规情况下5个分页连接的的起、止页码
                    start = self.current_page - 2
                    end = self.current_page + 2
            page_string = "<ul class=\"pagination\">"
            # 处理上一页
            if self.current_page_items.has_previous():
                page_string += "<li><a href=\"?page={}\"><span>&laquo;</span></a></li>".format(
                    self.current_page - 1)
            else:
                page_string += "<li class=\"disabled\"><a href=\"#\"><span>&laquo;</span></a></li>"
            # “首页”页码与 “...” 字样
            if self.current_page - 2 > 1:
                page_string += "<li class=\"active\"><a href=\"?page=1\">1</a></li>"
                page_string += "<li><a>...</a></li>"
            # 中间区域5个页码
            for i in range(start, end + 1):
                if i == self.current_page:
                    page_string += "<li class=\"active\"><a href=\"?page={0}\">{0}</a></li>".format(i)
                else:
                    page_string += "<li><a href=\"?page={0}\">{0}</a></li>".format(i)
            # “尾页”页码与 “...” 字样
            if self.current_page + 2 < self.django_paginator_obj.num_pages:
                page_string += "<li><a>...</a></li>"
                page_string += "<li><a href=\"?page={0}\">{0}</a></li>".format(self.django_paginator_obj.num_pages)
            if self.current_page_items.has_next():
                page_string += "<li><a href=\"?page={}\"><span>&raquo;</span></a></li>".format(
                    self.current_page + 1)
            else:
                page_string += "<li class=\"disabled\"><a href=\"#\"><span>&raquo;</span></a></li>"
            page_string += "</ul>"
            return mark_safe(page_string)
    

    最终效果

    image.png

    相关文章

      网友评论

          本文标题:在 Django 中实现分页

          本文链接:https://www.haomeiwen.com/subject/liplxdtx.html