Menu
CoddyTech

分页

本课属于 Coddy Django 学习旅程的“基于类的视图”单元。第 8 课,共 18 课。

作业页面会一次显示所有作业,数量达到 1000 个时就放不下了。分页会将列表拆分成多个页面,并在页面之间添加链接。ListView只需通过一个属性 paginate_by,就能拆分页面,这个属性表示每页显示的行数。

在食谱列表中设置 paginate_by = 20 后,/recipes/会显示前 20 条,/recipes/?page=2会显示接下来的 20 条。请求超出末尾的页面或非数字页码时,会收到 404 响应。模板中的列表只包含当前页面的行,模板还会获得 is_paginated 和表示当前页面的 page_obj。

页面链接需要你根据 page_obj 来编写:number表示当前页,paginator.num_pages表示总页数。若当前页之后或之前还有页面,has_next和 has_previous的值就是 True;next_page_number和 previous_page_number则会提供对应页面的页码:

{% if page_obj.has_next %}
  <a href="?page={{ page_obj.next_page_number }}">More recipes</a>
{% endif %}

记得为每个链接都保留条件判断:在最后一页,next_page_number会引发错误,导致页面崩溃。

challenge icon

挑战

简单

每页显示 5 个职位。

  1. 在 jobs/views.py 中,让 JobListView 每页显示 5 个职位。
  2. 在 job_list.html 中,在列表下方添加 <nav class="pages">,其中的链接文字必须准确写为 Previous 和 Next,并在两者之间显示来自 page_obj 的 Page 1 of 3。只有在对应页面存在时才显示链接,否则页面会崩溃。

打开 /jobs/ 并按下 Next:你会看到 Page 2 of 3。

亲手试试

from django.views.generic import DetailView, ListView, TemplateView

from .models import Job


class HomeView(TemplateView):
    template_name = "jobs/home.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["count"] = Job.objects.count()
        context["latest"] = Job.objects.order_by("-posted").first()
        return context


class AboutView(TemplateView):
    template_name = "jobs/about.html"


class JobListView(ListView):
    model = Job
    context_object_name = "jobs"
    ordering = ["-posted"]

    def get_queryset(self):
        jobs = super().get_queryset()
        city = self.request.GET.get("city")
        if city:
            jobs = jobs.filter(city=city)
        return jobs


class JobDetailView(DetailView):
    model = Job

基于类的视图中的所有课

自己练习: Django 在线编辑器