(最終更新月:2021年12月)
「Bootstrap モーダルの使い方が知りたい!」
「削除ページをもっとカッコよくできないの?」
というDjango初学者の方へ向けての記事となります
当記事では、削除ページの作成を通じて、
- Bootstrapのモーダルを使用する方法
- 削除モーダルのサンプル
を解説、紹介していきます
まずは「モダルってなに?」という方もいらっしゃるかと思いますので、ビフォーアフターからご覧ください!
✔YouTube解説動画
当記事の内容は動画を見ながら進めると、約15分程度で完了します。
動画ならではの情報も解説しているので、記事と一緒にご覧ください。
動画の概要欄には、単元ごとのコードを紹介しているgithubページも載せています。
ビフォーアフター
【ビフォー】
【アフター】
詳細ページで削除ボタンをクリックすると、モーダルが立ち上がる仕組みになっています
「DELETE」ボタンで値が削除されます
まずは、Bootstrapのモーダルを使用するための設定から確認していきましょう
Bootstrapモーダルの設定方法
scriptタグでpopper.jsとjavascript.jsを追加する必要があります
公式サイト記載の通り、</body>タグの直前に挿入しましょう
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
[参考:(Bundle版)Bootstrap 公式サイト(2021年12月時点)]※popper.jsとjavascript.jsが一つになっています
Components > Modalより近しいコードをコピペします(モーダルのページはこちら)
カスタマイズするにあたり、注意点を次章でご紹介します
モーダルの書き方
Bootstrapのサンプルコードから下記の点だけは注意してカスタマイズしてください
<!-- モダルを表示するボタン -->
<button type="button" ... data-bs-target="#staticBackdrop">
モーダルを表示
</button>
<!-- 表示されるモーダル -->
<div ... id="staticBackdrop" ....>
....
</div>
モーダルを表示するために下記が一致している必要があります
- ボタンの「data-bs-target」
- モーダルの「id」
ご自身でカスタマイズしていく際には気をつけましょう!
次章では参考として、日報アプリでの削除ページでの使用例をご紹介します
サンプルコードの紹介
下記のHTMLテンプレート上で「モーダル表示の為のボタン」と「モーダル」をそれぞれ記述します
- nippo-detail.htmlでモーダルの表示ボタンの設置
- nippo-delete.htmlでモーダルの記述
nippo-detail.html(モーダル表示ボタン)
{% extends 'base.html' %}
{% block content %}
<div class="container">
<div class="card mx-auto my-5 w-50" style="min-width:300px;">
<div class="card-header">
{{ object.timestamp }}
</div>
<div class="card-body">
<h3 class="card-title">{{ object.title }} </h3>
<p class="card-text">{{ object.content }}</p>
<div class="w-50">
<a href={% url 'nippo-update' object.pk %} class="btn btn-primary btn-sm">編集</a>
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#deleteModal-{{object.pk}}">削除</button>
{% include 'nippo/nippo-delete.html' %}
</div>
</div>
</div>
</div>
{% endblock %}
モーダルを表示するための下記を追記しています
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#deleteModal-{{object.pk}}">
削除
</button>
{% include 'nippo/nippo-delete.html' %}
includeタグで下記のnippo-delete.htmlを読み込んでいます
「data-bs-target」を”#deleteModal-{{object.pk}}“にしています
nippo-delete.html(モーダル)
<div class="modal fade" tabindex="-1" role="dialog" id="deleteModal-{{object.pk}}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">データの削除</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>削除すると元に戻すことはできません。よろしいでしょうか?</p>
</div>
<div class="modal-footer">
<form method="POST" action="{% url 'nippo-delete' object.pk %}">{% csrf_token %}
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-danger">DELETE</button>
</form>
</div>
</div>
</div>
</div>
モーダルのidを「deleteModal-{{object.pk}}」に指定してます
モーダルはHTML内の一つのパーツとしての記述となりますので、excludeタグやblockタグは不要です
formのaction先としてnippoDeleteView関数とすることで削除を実行しています
まとめ
今回のサンプルにおけるポイントとしては、
- モダルを呼び出す「data-bs-target」と「id」を同一にすること
- モダルファイルを別ファイルにすることで他のページでも使えるようにすること
になります
ちなみに、一覧ページのfor文内では下記のようになりましたので参考まで!
{% extends "base.html" %}
{% block head_title %}日報アプリ一覧{% endblock %}
{% block content %}
<div class="container">
<div class="mt-3 d-flex justify-content-end">
<a href={% url "nippo-create" %} class="btn btn-outline-primary float-right">
<i class="bi bi-plus"></i>
</a>
</div>
{% for obj in object_list %}
<div class="card my-3">
<div class="card-body">
<h5 class="card-title">
<a href={% url 'nippo-detail' obj.pk %}>
{{ obj.title}}
</a>
</h5>
<p class="card-text">
{{ obj.content }}
</p>
<a href={% url 'nippo-update' obj.pk %} class="card-link">
編集
</a>
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#deleteModal-{{obj.pk}}">削除</button>
</div>
</div>
{% include "nippo/nippo-delete.html" with object=obj %}
{% endfor %}
</div>
{% endblock %}
「リストビューではいらないよ!」という方はボタン自体をなくしても良いかもしれません
さて、次回はDjangoに備わっているとても便利な「クラスベースビュー」についての解説記事スタートです!
ビュー関数の代わりにクラスベースビューに変更すると、たったの3行で一覧ページが作れます!