ページネーション
CoddyのDjangoジャーニー「クラスベースビュー」セクションの一部。レッスン 8/18。
求人ページにはすべての求人が一度に表示されますが、1000件は収まりません。ページネーションを使うと、リストをページに分割し、ページ間をリンクで移動できるようになります。ListViewでは、1つの属性paginate_byで分割します。これは1ページあたりの行数です。
レシピ一覧でpaginate_by = 20を設定すると、/recipes/には最初の20件が表示され、/recipes/?page=2には次の20件が表示されます。最後のページを超えるページを指定すると、404が返されます。テンプレートのリストには現在のページの行だけが含まれ、テンプレートには現在のページを表すis_paginatedとpage_objも渡されます。
リンクは自分で記述します。page_objにはnumber、paginator.num_pages、has_next、next_page_number、has_previous、previous_page_numberがあります。
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">More recipes</a>
{% endif %}各リンクを囲む条件判定は必ず残してください。最後のページでは、next_page_numberがエラーを発生させ、ページがクラッシュするためです。
チャレンジ
簡単1ページに5件の求人を表示します:
JobListViewで、1ページあたり5件。job_list.htmlで、一覧の下に<nav class="pages">を配置し、Previousリンク、Page 1 of 3(実際の数値)のテキスト、Nextリンクを表示します。各リンクは、そのページが存在する場合にのみ表示されます。
Runを押し、/jobs/を開いて、Nextを押します。
自分で試してみよう
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プレイグラウンド