Phân trang
Thuộc phần View dựa trên lớp trong hành trình Django của Coddy. Bài học 8 trên 18.
Trang công việc hiển thị tất cả công việc cùng lúc, và không thể chứa được một nghìn công việc. Phân trang (pagination) chia danh sách thành nhiều trang với các liên kết giữa chúng. ListView chia danh sách bằng một thuộc tính, paginate_by, cho biết số hàng trên mỗi trang.
Với paginate_by = 20 trong danh sách công thức nấu ăn, /recipes/ hiển thị 20 công thức đầu tiên, /recipes/?page=2 hiển thị 20 công thức tiếp theo, còn trang nằm ngoài phạm vi hoặc trang có số trang không hợp lệ sẽ trả về phản hồi 404. Danh sách trong mẫu chỉ chứa các hàng của trang hiện tại, và mẫu cũng nhận được is_paginated cùng page_obj, tức trang hiện tại.
Bạn tự viết các liên kết từ page_obj: number là số trang hiện tại, còn paginator.num_pages là tổng số trang. has_next và has_previous có giá trị True khi có trang sau hoặc trang trước trang này, còn next_page_number và previous_page_number cho biết số trang đó:
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">More recipes</a>
{% endif %}Luôn giữ điều kiện kiểm tra quanh mỗi liên kết: ở trang cuối, next_page_number gây ra lỗi khiến trang bị sập.
Thử thách
DễHiển thị 5 việc làm trên mỗi trang.
- Trong
jobs/views.py, chỉnhJobListViewđể hiển thị 5 việc làm trên mỗi trang. - Trong
job_list.html, bên dưới danh sách, thêm<nav class="pages">với các liên kết có nội dung chính xác làPreviousvàNext, cùng vớiPage 1 of 3lấy từpage_objở giữa. Chỉ hiển thị mỗi liên kết khi có trang tương ứng, nếu không trang sẽ gặp lỗi.
Mở /jobs/ và nhấn Next: bạn sẽ thấy Page 2 of 3.
Tự làm thử
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
Tất cả bài học trong View dựa trên lớp
Tự luyện tập: Playground Django