详解Django的 paginate_by() 函数:指定每页显示的数量

  • Post category:Python

在Django中,paginate_by()是用于分页的函数,它允许您定义每页要显示的对象数量。本攻略将详细介绍paginate_by()的作用与使用方法。

作用

paginate_by()函数的作用是在视图中定义每页要显示的对象数量。它通常与Django中自带的分页器Paginator进行配合使用,让用户在浏览长列表时可以适当地分页浏览,提高用户体验。

使用方法

步骤一:引入Paginator和paginate_by函数

在views.py文件中引入Paginator和paginate_by:

from django.core.paginator import Paginator
from django.views.generic.list import ListView

步骤二:定义视图

接下来,在views.py文件中定义一个视图。这里我们使用ListView来展示一个模型的数据,这个模型是Article。

class ArticleListView(ListView):
    model = Article
    paginate_by = 10
    context_object_name = 'articles'
    template_name = 'article_list.html'

在这个视图中,我们使用ListView来展示Article模型的数据,并指定每页展示10个对象。我们还指定了context_object_name为articles,将展示的分页数据传入article_list.html模板中。注意,我们也可以使用paginate_by来定义每页显示的记录数。

步骤三:创建分页器

为了创建分页器,我们需要将我们的查询集传递给Paginator的构造函数。

class ArticleListView(ListView):
    queryset = Article.objects.all()
    paginate_by = 10
    context_object_name = 'articles'
    template_name = 'article_list.html'

    def get_queryset(self):
        return self.queryset.order_by('-pub_date')

    def get_context_data(self, **kwargs):
        context = super(ArticleListView, self).get_context_data(**kwargs)
        paginator = Paginator(self.queryset, self.paginate_by)
        page = self.request.GET.get('page')
        try:
            articles = paginator.page(page)
        except PageNotAnInteger:
            articles = paginator.page(1)
        except EmptyPage:
            articles = paginator.page(paginator.num_pages)
        context['articles'] = articles
        return context

在这里,我们首先定义了一个queryset属性,该属性是我们要分页的查询集,然后使用get_queryset()方法进行排序。然后我们更新了get_context_data()方法,创建了一个分页器的实例,获取模板中当前请求的页面(通过请求参数page的值),并尝试使用分页器实例的page()方法进行分页。如果传入的值不是数字,则默认为第一页。最后,将分页器的内容传递给模板中的页面。

步骤四:创建模板

最后,在模板文件中,我们需要遍历分页数据来显示每个文章。

<!-- article_list.html -->
{% extends "base.html" %}

{% block content %}
  {% for article in articles %}
    <div>
      <h2>{{ article.title }}</h2>
      <p>{{ article.body }}</p>
    </div>
  {% endfor %}

  <div class="pagination">
    <span class="step-links">
        {% if articles.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ articles.previous_page_number }}">previous</a>
        {% endif %}

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

        {% if articles.has_next %}
            <a href="?page={{ articles.next_page_number }}">next</a>
            <a href="?page={{ articles.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
  </div>
{% endblock %}

在这个模板中,我们首先展示每篇文章的标题和内容,在最后添加一个分页导航,其中包括上一页、下一页、第一页和最后一页的链接。

示例

这里提供两个实例,以便更好地理解paginate_by函数的用途和使用方法。

示例一

假设有一个在线商店网站,有一个商品列表页面,需要将所有商品进行分页,并每页显示10个商品。

from django.core.paginator import Paginator
from django.views.generic.list import ListView
from .models import Product

class ProductListView(ListView):
    model = Product
    paginate_by = 10
    context_object_name = 'products'
    template_name = 'product_list.html'

在这个视图中,我们定义了商品分页的页面,每页显示10个商品,并将查询集命名为products。我们还指定了template_name为product_list.html,以便在这个页面中展示分页器和产品信息。

<!-- product_list.html -->
{% extends "base.html" %}

{% block content %}
  {% for product in products %}
    <div>
      <h2>{{ product.name }}</h2>
      <p>{{ product.description }}</p>
    </div>
  {% endfor %}

  <div class="pagination">
    <span class="step-links">
        {% if products.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ products.previous_page_number }}">previous</a>
        {% endif %}

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

        {% if products.has_next %}
            <a href="?page={{ products.next_page_number }}">next</a>
            <a href="?page={{ products.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
  </div>
{% endblock %}

在模板中,我们简单地遍历每个产品,并添加一个分页导航。

示例二

假设有一个博客网站,需要将所有文章进行分页,并每页显示5篇文章。

from django.core.paginator import Paginator
from django.views.generic.list import ListView
from .models import Post

class PostListView(ListView):
    model = Post
    paginate_by = 5
    context_object_name = 'posts'
    template_name = 'post_list.html'

在这个视图中,我们定义了文章分页的页面,每页显示5篇文章,并将查询集命名为posts。我们还指定了template_name为post_list.html,以便在这个页面中展示分页器和文章信息。

<!-- post_list.html -->
{% extends "base.html" %}

{% block content %}
  {% for post in posts %}
    <div>
      <h2>{{ post.title }}</h2>
      <p>{{ post.text }}</p>
    </div>
  {% endfor %}

  <div class="pagination">
    <span class="step-links">
        {% if posts.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ posts.previous_page_number }}">previous</a>
        {% endif %}

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

        {% if posts.has_next %}
            <a href="?page={{ posts.next_page_number }}">next</a>
            <a href="?page={{ posts.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
  </div>
{% endblock %}

在模板中,我们简单地遍历每篇文章,并添加一个分页导航。

总结

paginate_by()函数是一个非常有用的Django视图函数,它允许我们非常简单地显示分页数据,提高用户体验。我们只需要在ListView视图中指定paginate_by属性,然后在模板中遍历分页对象即可。通过使用Paginator和Paginate_by()创建分页器,我们可以轻松地定义每页的记录数,并在模板中展示分页数据,改善网站的交互性。