分页
本课属于 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会引发错误,导致页面崩溃。
挑战
简单每页显示 5 个职位。
- 在
jobs/views.py中,让JobListView每页显示 5 个职位。 - 在
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 在线编辑器