Menu
CoddyTech

ページネーション

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がエラーを発生させ、ページがクラッシュするためです。

challenge icon

チャレンジ

簡単

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プレイグラウンド