【Django】モーダルを使ったデリートビューの実装方法を解説

※本サイトにはプロモーション・広告が含まれています。

(最終更新月:2021年12月)

「Bootstrap モーダルの使い方が知りたい!」

「削除ページをもっとカッコよくできないの?」

というDjango初学者の方へ向けての記事となります

当記事では、削除ページの作成を通じて、

  • Bootstrapのモーダルを使用する方法
  • 削除モーダルのサンプル

を解説、紹介していきます

まずは「モダルってなに?」という方もいらっしゃるかと思いますので、ビフォーアフターからご覧ください!

✔YouTube解説動画

当記事の内容は動画を見ながら進めると、約15分程度で完了します。

動画ならではの情報も解説しているので、記事と一緒にご覧ください。

動画の概要欄には、単元ごとのコードを紹介しているgithubページも載せています。

✔独学におすすめ

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

ビフォーアフター

【ビフォー】

【アフター】

詳細ページで削除ボタンをクリックすると、ダルが立ち上がる仕組みになっています

「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テンプレート上で「モーダル表示の為のボタン」と「モーダル」をそれぞれ記述します

  1. nippo-detail.htmlでモーダルの表示ボタンの設置
  2. 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">&times;</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行で一覧ページが作れます!

タイトルとURLをコピーしました