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

  • Post category:Python

page_kwarg() 是 Django 的一个分页器函数。它作用在当前视图的查询集上,根据请求参数中无需分页的其他参数,生成一个分页器并将其作为上下文传递到模板中。这个函数接收一个 page_kwarg 参数,用于指定分页器的名称。若未设置,则使用默认值 page

下面是 page_kwarg() 的使用方法:

1.引入 Django 相关模块:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.views.generic import ListView

2.在视图中使用 page_kwarg()

class MyListView(ListView):
    model = MyModel
    queryset = MyModel.objects.all()
    paginate_by = 10
    template_name = 'my_template.html'
    context_object_name = 'my_list'
    page_kwarg = 'page_number'

在以上示例中,我们自定义了分页器名称 page_number

3.添加分页器到模板中:

{% if is_paginated %}
    <div class="pagination">
        <span class="step-links">
            {% if page_obj.has_previous %}
                <a href="?page={{ page_obj.previous_page_number }}">previous</a>
            {% endif %}

            <span class="current-page">
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            </span>

            {% if page_obj.has_next %}
                <a href="?page={{ page_obj.next_page_number }}">next</a>
            {% endif %}
        </span>
    </div>
{% endif %}

这个模板代码片段展示了包含页码链接的基本 HTML 样式。

接下来,我们提供两个 page_kwarg() 的示例:

  1. 假设有一个博客应用,用户想要通过日期筛选博客文章。我们可以使用 page_kwarg() 来分页并展示这个过滤后的结果列表。

视图代码:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.views.generic import ListView
from .models import Blog

class BlogListView(ListView):
    model = Blog
    template_name = 'blog_list.html'
    context_object_name = 'blog_list'
    paginate_by = 10
    allow_empty = True
    page_kwarg = 'page_number'

    def get_queryset(self):
        queryset = super().get_queryset()
        date_filter = self.request.GET.get('date')
        if date_filter:
            queryset = queryset.filter(date=date_filter)
        return queryset

在这个示例中,我们根据用户在查询字符串中传入的 date 进行过滤。如果没有传入 date 参数,我们将返回整个博客列表。我们设置 page_kwargpage_number,这样在我们的模板中,我们可以使用这个参数名来生成我们的分页器。

2.假设我们想展示一个包含所有商品的产品目录,并使用 page_kwarg() 对它进行分页。我们还将使用 Django 的 Q() 对象和逻辑运算符来创建一个高级查询表达式。我们还将使用逻辑运算符 exclude 来排除当前促销的商品,而这些商品包含在另一个过滤条件的查询集中。这里我们提供一个简化版本的示例:

视图代码:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.views.generic import ListView
from django.db.models import Q
from .models import Product

class ProductListView(ListView):
    model = Product
    template_name = 'product_list.html'
    context_object_name = 'product_list'
    paginate_by = 12
    allow_empty = True
    page_kwarg = 'page_number'

    def get_queryset(self):
        queryset = super().get_queryset()

        # 构建查询表达式
        query = Q(price__lt=50) | Q(category='clothes')
        excluded_query = Q(promotion=True)
        queryset = queryset.filter(query).exclude(excluded_query)

        return queryset

在这个示例中,我们构建了一个查询表达式,使用了逻辑运算符 |&,使用 Q() 对象构建了一个复杂的查询。

使用 exclude() 搜索并排除任何在 excluded_query 中出现的商品。最后,我们将搜索结果网页化,并将 page_kwarg 设置为 page_number,以便在模板中使用。