本文对django分页再封装,支持自定义每页数据量,页码数量,是否保留原url请求参数。直接返回页码html。

 

 页码数量

默认采用百度的分页模式,只显示10页,可自定义。

django分页再封装_Python

 

1.总页数少于10页,页面上显示所有页码

2.如果当前页是前6页,显示1-10页

3.如果当前页是后5页,显示后10页
4.其他情况,中间部分,显示当前页的前5页,当前页,当前页的后4页
django分页再封装_当前页_02
django分页再封装_html_03

django分页再封装_分页_04

django分页再封装_当前页_05

 

 

封装分页

自行放到一个包下

参数见注释,

必传

  queryset queryset 要分页的查询集

  page int 第几页

  base_url str 原url路径

可选

  query_params QueryDict 原url参数,默认为空

  page_size int 每页数据量,默认20条

  page_count int 页码数量,默认10页

返回值

  分页后的queryset

  页码html

from django.core.paginator import Paginator
from django.utils.safestring import mark_safe
from django.http import QueryDict


def pagination(queryset, page, base_url, query_params=QueryDict(), page_size=20, page_count=10):
    """
    分页组件
    :param queryset: 要分页的查询集
    :param page: 第几页
    :param base_url: 基础URL:/goods/
    :param query_params: QueryDict对象,内部含所有当前URL的原条件?a=1&b=2&a=3
    :param page_size: 每页显示数据条数,默认每页20条
    :param page_count: 共显示多少个页码按钮,默认10页
    :return: 该页的查询集, 页码的html: li
    """
    # 对数据进行分页
    paginator = Paginator(queryset, page_size)

    # 获取第page页的内容

    try:
        page = int(page)
    except Exception as e:
        page = 1
    if page > paginator.num_pages:
        page = 1

    # 获取第page页的Page对象
    content_page = paginator.page(page)

    # todo: 进行页码控制,页面上最多显示n个页码,以5为例
    # 1.总页数少于5页,页面上显示所有页码
    # 2.如果当前页是前3页,显示1-5页
    # 3.如果当前页是后3页,显示后5页
    # 4.其他情况,中间部分,显示当前页的前2页,当前页,当前页的后2页
    num_pages = paginator.num_pages  # 总页数
    if num_pages < page_count:
        pages = range(1, num_pages + 1)
    elif page <= (page_count//2)+1:
        pages = range(1, page_count+1)
    elif num_pages - page < page_count//2:
        pages = range(num_pages-page_count+1, num_pages + 1)
    else:
        if page_count%2 == 0:
            pages = range(page-(page_count//2), page+(page_count//2))
        else:
            pages = range(page-(page_count//2), page+((page_count//2)+1))

    page_list = []
    query_params._mutable = True
    # 上一页
    if content_page.has_previous():
        query_params['page'] = content_page.previous_page_number()
        prev = '<li><a href="%s?%s">上一页</a></li>' % (base_url, query_params.urlencode())
        # 可选去首页
    else:
        prev = '<li class="disabled"><a href="javascript:;">上一页</a></li>'
    page_list.append(prev)

    # 页码列表
    for pindex  in pages:
        if pindex == content_page.number:
            tpl = '<li class="active"><a href="javascript:;">%s</a></li>' % pindex
        else:
            query_params['page']= pindex
            tpl = '<li><a href="%s?%s">%s</a></li>' % (base_url, query_params.urlencode(), pindex)
        page_list.append(tpl)
    
    # 下一页
    if content_page.has_next():
        query_params['page'] = content_page.next_page_number()
        next = '<li><a href="%s?%s">下一页</a></li>' % (base_url, query_params.urlencode(),)
        # 可选去尾页
    else:
        next = '<li class="disabled"><a href="javascript:;">下一页</a></li>'
    page_list.append(next)

    # 可选  共100条数据,页码1/10页
    if content_page.count:
        tpl = "<li class='disabled'><a>共%s条数据,页码%s/%s页</a></li>" % (
        queryset.count(), page, num_pages)
        page_list.append(tpl)

    return content_page, mark_safe("".join(page_list))

 

 

视图使用

request.path_info:当前的url路径
request.GET:当前的url其他参数,
def index(request):
    queryset = Goods.objects.all()
    content_page, page_html = pagination(queryset, 
            page=request.GET.get('page'),
            base_url=request.path_info, 
            query_params=request.GET, page_size=10,page_count=10)
    return render(request, 'index.html', {'content_page': content_page, 'page_html ': page_html })

 

 

 前端使用

极其简单

只要循环分页内容,和使用页码html即可

前端以bootstrap为例,只需要把page_html包在<ul class="pagination">内即可

{% for item in content_page %}
    <div>{{item}}</div>
{% endfor %}

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