サイトアイコン 知的好奇心

DjangoでBootstrap4を用いたページネーションを設定する方法

DjangoでBootstrap4を用いたページネーションを設定する方法をご紹介します。

条件

前提

models.py

以下のようなModelが存在するものとします。

from django.db import models
from django.urls import reverse
from django.contrib.auth.models import AbstractUser


class CustomUser(AbstractUser):

    def __str__(self):
        return self.username + ":" + self.email


class Post(models.Model):
    """投稿モデル"""
    class Meta:
        db_table = 'post'

    title = models.CharField(verbose_name='タイトル', max_length=255)
    text = models.CharField(verbose_name='内容', max_length=255, default='', blank=True)
    author = models.ForeignKey(
        'sample.CustomUser',
        on_delete=models.CASCADE,
    )
    created_at = models.DateTimeField(verbose_name='登録日時', auto_now_add=True)
    updated_at = models.DateTimeField(verbose_name='更新日時', auto_now=True)

    def __str__(self):
        return self.title + ',' + self.text

    @staticmethod
    def get_absolute_url(self):
        return reverse('sample:index')

DBレコード

以下のように10件のレコードが存在するものとします。

views.py

generic.ListViewを用いて「paginate_by = 3」を指定します。

import logging
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import generic
from .models import Post

logger = logging.getLogger('development')


class IndexView(LoginRequiredMixin, generic.ListView):

    paginate_by = 3
    template_name = 'sample/index.html'
    model = Post

ページネーションの実装

django-bootstrap4

以下のURLを参照して「django-bootstrap4」をインストールします。

https://pypi.org/project/django-bootstrap4/

base.html

以下はbase.htmlの抜粋です。
<!– Bootstrap4 –>で囲まれた箇所を記述して「django-bootstrap4」を読み込むようにします。

{% load staticfiles %}
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Bootstrap4 -->
        {% load bootstrap4 %}
        {% bootstrap_css %}
        {% bootstrap_javascript jquery='full' %}
        <!-- Bootstrap4 -->

        <title>{% block title %}Blog{% endblock %}</title>
    </head>

pagination.html

base.htmlと同じディレクトリに以下のような「pagination.html」を作成します。

<div class="container">
    <div class="row">
        <div class="col-md-6 offset-md-3 py-2">
            <nav aria-label="ページ送り">
                <div class="text-center">
                    <ul class="pagination justify-content-center">
                        {% if page_obj.has_previous %}
                            <li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}">&laquo;</a></li>
                        {% else %}
                            <li class="page-item disabled"><span class="page-link">&laquo;</span></li>
                        {% endif %}
                        {% for i in page_obj.paginator.page_range %}
                            {% if page_obj.number == i %}
                                <li class="page-item active" aria-current="page">
                                    <a class="page-link" href="#">{{ i }} <span class="sr-only">(現位置)</span></a>
                                </li>
                            {% else %}
                                <li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
                            {% endif %}
                        {% endfor %}
                        {% if page_obj.has_next %}
                            <li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}">&raquo;</a></li>
                        {% else %}
                            <li class="page-item disabled"><span class="page-link">&raquo;</span></li>
                        {% endif %}
                    </ul>
                </div>
            </nav>
        </div>
    </div>
</div>

index.html

base.htmlをextendsして、pagination.htmlをincludeします。

{% extends 'base.html' %}

{% block content %}
<div class="col-lg-6 offset-lg-3">

    {% if user.is_authenticated %}
        <h1>ユーザ名</h1>
        <p class="user-name">{{ user.username }} でログイン中です。</p>
    {% endif %}

    <h1>Post List</h1>

    <section class="post-list">
        <ul>
            {% for post in object_list %}
            <li>
                <table class="table table-bordered">
                    <tbody>
                        <tr>
                            <th width="35%">タイトル</th>
                            <td width="65%">{{ post.title }}</td>
                        </tr>
                        <tr>
                            <th>内容</th>
                            <td>{{ post.text }}</td>
                        </tr>
                    </tbody>
                </table>
            </li>
            {% empty %}
            <li class="no-post">
                <p>記事が存在しません。</p>
            {% endfor %}
        </ul>
    </section>
    <div class="col-6 offset-3 justify-content-center">
        {% if is_paginated %}
            {% include 'pagination.html' %}
        {% endif %}
    </div>
</div>

{% endblock %}

実行結果

以下のように良い感じのページネーションが表示されます。

参考

How to Paginate with Django

https://simpleisbetterthancomplex.com/tutorial/2016/08/03/how-to-paginate-with-django.html

Bootstrap4以降ガイド

https://cccabinet.jpn.org/bootstrap4/components/pagination

stackoverflow:Centering the pagination in bootstrap

https://stackoverflow.com/questions/15265253/centering-the-pagination-in-bootstrap

stackoverflow:Bootstrap 4 Center Pagination in Column

https://stackoverflow.com/questions/43679491/bootstrap-4-center-pagination-in-column

モバイルバージョンを終了