详解Django的 get_paginate_by() 函数:获取每页显示的数量

  • Post category:Python

get_paginate_by()函数是Django框架中用于控制分页大小的函数,它可以控制每页显示的数据条数,以实现在数据量过多的情况下,对数据进行分页显示。

对于使用Django框架的Web应用程序而言,如果需要使用分页,就需要在views.py 文件中定义一个类,并在其中重写get_paginate_by(self, queryset)方法,实现每页返回指定数量的查询结果的目的。

get_paginate_by()函数的语法格式如下:

def get_paginate_by(self, queryset):
    pass

其中self参数指向视图对象本身,queryset参数是Django查询集对象,即从数据源中获取数据的一种方式。

下面,提供两个实例说明:

例1:对于一个简单的博客应用,需要显示每页10篇文章并支持分页

  1. 在views.py 文件中定义类:
from django.views.generic import ListView
from .models import Blog

class BlogListView(ListView):
    model = Blog
    template_name = 'blog.html'
    paginate_by = 10

在定义类时,指定了每页展示10篇文章,并从model = Blog声明的Blog表中获取。使用分页是通过定义paginate_by属性实现的。

  1. 在模板文件blog.html中进行分页渲染:
{% if is_paginated %}
<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <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>
            <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
</div>
{% endif %}

{% for blog in object_list %}
<div class="post">
    <h2>{{ blog.title }}</h2>
    <p>{{ blog.body }}</p>
</div>
{% endfor %}

在模板文件中,使用page_objpaginator属性来展示分页信息。在循环中使用 object_list 属性来展示文章列表。

例2:对于一个简单的图书出售应用,需要显示每页8本书并支持分页

  1. 在views.py 文件中定义类:
from django.core.paginator import Paginator
from django.shortcuts import render
from .models import Book

def book_list(request):
    book_list = Book.objects.all()
    paginator = Paginator(book_list, 8) 
    page = request.GET.get('page')    
    books = paginator.get_page(page)   

    return render(request, 'book_list.html', {'books': books})

在定义函数时,使用Paginator类实现分页属性的设置。并指定每页展示8本书。使用get_page()方法获取当前页码的数据。

  1. 在模板文件book_list.html中进行分页渲染:
{% if books.has_other_pages %}
    <nav aria-label="Page navigation">
      <ul class="pagination">
      {% if books.has_previous %}
          <li><a href="?page=1"><<</a></li>
          <li><a href="?page={{ books.previous_page_number }}"><</a></li>
      {% endif %}

      {% for i in books.paginator.page_range %}
          {% if books.number == i %}
              <li class="active"><a href="?page={{ i }}">{{ i }} <span class="sr-only">(current)</span></a></li>
          {% else %}
              <li><a href="?page={{ i }}">{{ i }}</a></li>
          {% endif %}
      {% endfor %}

      {% if books.has_next %}
          <li><a href="?page={{ books.next_page_number }}">></a></li>
          <li><a href="?page={{ books.paginator.num_pages }}">>></a></li>
      {% endif %}
      </ul>
    </nav>
{% endif %}

<div class="container">
    <div class="row">
    {% for book in books %}
        <div class="col-md-3">
            <div class="card mb-3">
                <div class="card-body">
                    <h5 class="card-title">{{ book.title }}</h5>
                    <p class="card-text">{{ book.author }}</p>
                </div>
            </div>
        </div>
    {% endfor %}
    </div>
</div>

在模板文件中,使用Paginator类的 page_range 属性展示分页信息。在循环中使用books 属性来展示书籍列表。