详解Django的 page_kwarg() 函数:指定分页查询参数的名称

  • Post category:Python

page_kwarg() 是 Django 中的一个函数,在处理分页查询时非常有用。它用于告知 Django 在分页时,需要的参数名称是什么。下面详细讲解 page_kwarg() 函数的作用及使用方法,并提供两个实例进行说明。

page_kwarg() 函数的作用

当使用 Django 的分页功能时,我们经常需要控制当前页的页码,这个页码通常是从 URL 引导参数中获取的,比如 /article/?page=3 的 URL 中的 page 参数就是当前页码。在处理这种情况时,需要告诉 Django 分页模块我们期望的页码参数名称是什么,这个时候就需要使用 page_kwarg() 函数。

page_kwarg() 函数的使用方法

page_kwarg() 函数一般在视图函数中调用,它只需要传入一个参数,即我们希望分页模块使用的参数名,比如 page

from django.views.generic import ListView

class ArticleListView(ListView):
    model = Article
    template_name = 'article_list.html'
    paginate_by = 20
    page_kwarg = 'page'

在上面的例子中,page_kwarg 参数的值被设置为 'page',这个参数名就会成为分页模块获取当前页码时的引导参数。在我们的URL中,只要将页码参数名设置为 'page',就可以获取正确的页码了。

实例一

假设我们现在有一个博客网站,需要展示所有文章的列表,我们希望每页显示 5 篇文章,并且我们希望使用 page 作为页码参数名称。下面是代码实现:

from django.views.generic import ListView
from .models import Article

class ArticleListView(ListView):
    model = Article
    template_name = 'article_list.html'  # 指定模板名称
    paginate_by = 5                      # 每页显示的文章数量
    page_kwarg = 'page'                  # 指定页码参数名

在模板(article_list.html)中,我们可以通过 page_obj 这个模板变量获取到当前页的 page 对象,并通过 paginator 变量获取到 Paginator 对象。比如,我们可以这样实现分页链接:

{% if page_obj.has_previous %}
    <a href="?{% if page_obj.previous_page_number %}page={{ page_obj.previous_page_number }}{% endif %}">
        &laquo; 上一页
    </a>
{% endif %}

{% for num in paginator.page_range %}
    {% if num == page_obj.number %}
        <span>{{ num }}</span>
    {% else %}
        <a href="?page={{ num }}">{{ num }}</a>
    {% endif %}
{% endfor %}

{% if page_obj.has_next %}
    <a href="?{% if page_obj.next_page_number %}page={{ page_obj.next_page_number }}{% endif %}">
        下一页 &raquo;
    </a>
{% endif %}

实例二

假设我们现在有一个代办事项应用,需要向用户展示所有的待办列表,并且支持分页功能。我们希望使用 p 作为页码参数名称。下面是代码实现:

from django.core.paginator import Paginator
from django.shortcuts import render
from .models import Task

def task_list(request):
    queryset = Task.objects.all()
    paginator = Paginator(queryset, 10, request.GET.get('p', 1)) # 设置每页显示10个任务,获取页码参数为 'p'
    page_obj = paginator.page(paginator.num_pages)             # 获取当前页对象

    context = {
        'task_list': page_obj.object_list,  # 当前页的任务列表
        'page_obj': page_obj,
    }
    return render(request, 'task_list.html', context)

在模板中,我们可以使用和实例一一样的方法实现分页链接。例如:

{% if page_obj.has_previous %}
    <a href="?{% if page_obj.previous_page_number %}p={{ page_obj.previous_page_number }}{% endif %}">
        &laquo; 上一页
    </a>
{% endif %}

{% for num in paginator.page_range %}
    {% if num == page_obj.number %}
        <span>{{ num }}</span>
    {% else %}
        <a href="?p={{ num }}">{{ num }}</a>
    {% endif %}
{% endfor %}

{% if page_obj.has_next %}
    <a href="?{% if page_obj.next_page_number %}p={{ page_obj.next_page_number }}{% endif %}">
        下一页 &raquo;
    </a>
{% endif %}

通过上述示例,我们就可以使用 page_kwarg() 函数对查询结果进行分页,并实现分页链接功能。