Django側で予めページネーション用のパッケージ、django.core.paginator を用意してくれています。
例として MyModel というモデルのインスタンスを一覧表示し、ページネーションを導入します。
from django.core.paginator import Paginator
from django.views.generic import ListView
from .models import MyModel
class MyModelListView(ListView):
model = MyModel
paginate_by = 10 # 1ページあたりの表示数
def get_queryset(self):
queryset = super().get_queryset()
# このメソッドでクエリセットを加工することができます。
return queryset.order_by('-created_at')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
paginator = context['paginator']
page_numbers_range = 10 # ページ番号の表示数
max_index = len(paginator.page_range)
page = self.request.GET.get('page')
current_page = int(page) if page else 1
start_index = int((current_page - 1) / page_numbers_range) * page_numbers_range
if start_index + page_numbers_range > max_index:
end_index = max_index
else:
end_index = start_index + page_numbers_range
context['page_numbers'] = paginator.page_range[start_index:end_index]
return context
get_queryset メソッドで、モデルのクエリセットを加工しています。ここでは、 created_at フィールドで並び替えていますが、必要に応じて変更してください。
また、 get_context_data メソッドで、テンプレートに渡すデータに、ページ番号を含めています。
テンプレートでのページ番号の表示方法は、以下のようになります。
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">前へ</a>
{% endif %}
{% for i in page_numbers %}
{% if page_obj.number == i %}
<strong>{{ i }}</strong>
{% else %}
<a href="?page={{ i }}">{{ i }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">次へ</a>
{% endif %}
page_obj は、 get_context_data メソッドで追加した Page オブジェクトです。
このオブジェクトには、現在のページや前後のページの情報が含まれています。







