Django分页

我们要实现如下样子的分页界面

pagination ui

在不借助于第三方Django APP的情况下,仅仅使用Django框架提供的分页(Pagination)机制,该如何做呢?

视图中的分页处理

下面展示如何在视图中使用Paginator对一个queryset进行分页。假如我们需要对单品展示进行分页,单品的model叫做SKU.

from django.shortcuts import render
from django.core.paginator import PageNotAnInteger, Paginator, EmptyPage

def list_skus(request):
    skus = SKU.objects.all()
    # 分页,每页展示32项
    paginator = Paginator(skus, 32)
    page = request.GET.get('page')
    try:
        skus = paginator.page(page)
    except PageNotAnInteger:
        # 如果page不是整数,则展示第1页
        skus = paginator.page(1)
    except EmptyPage:
        # 如果page超过范围,则展示最后一页
        skus = paginator.page(paginator.num_pages)
    return render(request, 'list_skus.html', {'skus': skus})

模板中的分页处理

上面的视图示例中最后会渲染模板list_skus.html,在该模板(使用Bootstrap框架)中,分页示例如下:

{% if skus.has_previous %} {% else %} {% endif %} {{skus.number}} of {{skus.paginator.num_pages}} {% if skus.has_next %} {% else %} {% endif %}

等等,上面模板中的query_params是什么鬼?为什么需要加上query_params?当我们对查询结果进行分页的时候,视图对应的URL地址一般会包含查询参数。这些查询参数不能丢,因此必须在视图和模板中显式地处理这些参数。视图中先获取查询参数,然后把查询参数放到上下文里面传给render方法。如下所示:

def list_skus(request):
    # ...
    query_params = request.GET.copy()
    query_params.pop('page', None)  # delete page param
    # ...
    context = {
        'page': page,
        'paginator': paginator,
        'query_params': query_params,
        'skus': skus,
    }
    return render(request, 'list_skus.html', context)

参考

  • Django Pagination

你可能感兴趣的:(Django分页)