Django入門 | 初心者でも1時間でWebアプリ(Todoアプリ)を作成するコース

こんにちは、はやたす(@hayatasuuu )です。

この記事では「Django(ジャンゴ)を使ってTodoアプリを作成する方法」を紹介します。

おそらく、あなたはこんな状況ではないでしょうか?

  • Pythonを使って、Webアプリを開発してみたい
  • とりあえず、最も基本的なアプリケーションを作ってみたい
  • しかも、初心者でも分かるくらい丁寧に解説してほしい

安心してください。

この記事に沿って学習すれば、たとえ初心者だとしてもDjangoを使ってTodoアプリを開発できるようになります。

Django Todo 入門

しかも、たったの1時間だけで、です。

もし他の学習リソースで理解できなかったなら、ぜひこの記事を参考にしてみてください。

元スクール講師であり、YouTubeで2.4万人以上にプログラミングを教えている僕が丁寧に解説していきます。

このチュートリアルで必要な事前知識
  • ProgateレベルのPythonスキルがあること
  • ProgateレベルのHTML/CSSスキルがあること
  • VSCodeを操作できること
  • (Nice to have)ターミナル操作・Linuxコマンドの知識

※完成したTodoアプリは以下に置いておきます!

GitHub
GitHub - hayatasuuu/djangotodo Contribute to hayatasuuu/djangotodo development by creating an account on GitHub.
目次

STEP1 : Djangoアプリ作成の準備をする

さて、さっそくDjangoを使ってアプリを開発していきましょう。

細かいことは後回し。まずは作ってみることが重要です。
STEP1では、Djangoでアプリ開発するための準備をします。

紹介するトピックは次のとおりです。

  • プロジェクトフォルダの作成
  • 必要なライブラリのインストール

一緒に手を動かしていきましょう。

プロジェクトフォルダの作成

今回のアプリ開発で使うプロジェクトフォルダを作成しましょう。

好きな場所にフォルダを作成すれば大丈夫です。
僕は/Users/hayato/dev/の下にプロジェクトフォルダを作成します。

ターミナルを使える環境なら以下のコマンド、そうでないなら右クリックでフォルダを作成しましょう。

$ mkdir djangotodo

作成が完了したら、djangotodoに移動します。

$ cd djangotodo
$ pwd
# /Users/hayato/dev/djangotodo

このフォルダをVSCodeで開きましょう。
今後はVSCodeのターミナルを使っていきます。

必要なライブラリのインストール

このチュートリアルでは、Python3.9を使っていきます。

$ python -V
# Python 3.9.7

今だったらPython3.8以降にするのがおすすめです。
2021年12月以降にリリースされるDjango4系では、Python3.8以降のサポートになります。

参考 : https://docs.djangoproject.com/en/dev/releases/4.0/

Python3.8以降の準備ができていれば、ライブラリのインストールを進めましょう。

まずpipコマンドをアップグレードし、そのあとでDjangoをインストールします。

$ pip install --upgrade pip
$ pip install django

無事にインストールできたら、pip listで確認してみましょう。

$ pip list
# Package    Version
# ---------- -------
# asgiref    3.4.1
# Django     3.2.8
# pip        21.3.1
# pytz       2021.3
# setuptools 57.5.0
# sqlparse   0.4.2
# wheel      0.37.0

僕の環境に入っているライブラリは上記のとおりです。

Djangoはバージョン3.2になっています。
もし自分でエラー修正する自信がなければ、バーションを合わせてインストールするのがおすすめです。

$ pip install django==3.2.8

これでPythonとDjangoの準備が完了しました。

STEP2 : Djangoアプリ作成の初期設定をおこなう

STEP2ではDjangoアプリ開発の初期設定をおこないます。
Djangoではあらかじめアプリ開発に必要なパーツを準備されています。

だから自分が作りたいアプリに合わせて、設定を少しだけ変更すれば土台の部分が完成します。

具体的には、以下の設定をおこないます。

  • Djangoプロジェクトを開始する
  • サーバーを立ち上げてロケットを飛ばす
  • アプリを作成する
  • 初期設定をおこなう

それでは順番に見ていきましょう。

Djangoプロジェクトを開始する

Djangoでアプリ開発するとき「プロジェクト」を開始する必要があります。

プロジェクト名はなんでも大丈夫です。
ここではconfigという名前にしておきたいと思います。

configという名前でプロジェクトを開始するには、以下のコマンドをターミナルに入力しましょう。

$ django-admin startproject config .

このコマンドを実行しても、ターミナル上では何の変化もありません。

でもよくみると、新しいファイルとフォルダが作成されているはずです。

$ ls
# config  manage.py

configはプロジェクトフォルダです。ここに各種設定を記入していきます。

manage.pyはDjangoで色々な操作をおこなうためのファイルです。

具体的にどんな操作ができるのか、さっそく見ていきましょう。

サーバーを立ち上げてロケットを飛ばす

先ほど作成したmanage.pyを使って、Djangoでロケットを飛ばしてみます。

ロケットを飛ばす…というのは、サーバーを立ち上げることを意味しています。

以下のコマンドを入力してみてください。

$ python manage.py runserver

赤文字の警告は後で解消できます。今は気にしなくて大丈夫です。
それよりもhttp://localhost:8000にアクセスしてみてください。

サーバーが立ち上がり、ロケットが発射されているはずです。

これでサーバーの立ち上げまで完了しました。
最終的にはプログラムを書いていくことで、ロケットの代わりにTodoアプリが表示されます。

アプリを作成する

さて。ここまでプロジェクトの作成と、サーバーの立ち上げまで完了しました。

次にやるべきことは「アプリ」の作成です。

もしサーバーを立ち上げたままだったらctrl + cで停止してから、以下のコマンドをターミナルに入力しましょう。

$ python manage.py startapp todo

ターミナル上の変化は何もありません。
その代わりに新しくtodoというフォルダが作成できています。

$ ls
# config  db.sqlite3  manage.py  todo

これでアプリを作成できました。
ここでいうアプリというのは、”機能”みたいなイメージです。

以下にDjango公式で書かれている説明を載せておきます。

プロジェクトとアプリケーション

プロジェクトとアプリの違いは何でしょうか? アプリとは、ウェブログシステム、公的記録のデータベース、小規模な投票アプリなど、何かを行う Web アプリケーションです。プロジェクトは、特定のウェブサイトの構成とアプリのコレクションです。プロジェクトには複数のアプリを含めることができます。 アプリは複数のプロジェクトに存在できます。

Todoアプリだとイメージじづらいので、YouTubeで考えてみましょう。

YouTubeでは、1つのアプリケーションに色々な機能が備わっています。

  • ビデオの配信機能
  • 最近はやりのショートムービー機能
  • 映画やドラマをレンタル・購入できる機能

これらをまとめて”YouTube”が作られていますよね?

もしDjangoでYouTubeを作るとなれば、まずYouTubeプロジェクトを準備して、その中に各機能を構成するアプリを開発していくことになります。

今回はTodoアプリ1つだけ開発するので、複数のアプリは登場しません。1つだけです。

初期設定をおこなう

最後に以下の初期設定をおこないます。

  • アプリの登録
  • 使用する言語とタイムゾーンの変更

Djangoでは作成するアプリ(=機能)をプロジェクトに登録する必要があります。

また、僕たちは日本人なので言語を日本語にしましょう。タイムゾーンも東京に変更します。

Djangoの設定はdjangotodo/settings.pyに書かれています。
下にスクロールして、INSTALLED_APPS/LANGUAGE_CODE/TIME_ZONEの3つを探してください。

見つかったら以下のように設定を書き換えます。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'todo.apps.TodoConfig' # 追加
]

# (中略)

# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ja'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Tokyo'

これで初期設定は完了です。
試しにpython manage.py runserverでサーバーを立ち上げてみましょう。

しっかり日本語に切り替わっているはずです。

STEP3 : DjangoでHello Worldを表示してみる

そろそろロケットを飛ばすのに飽きてきたと思います。

ロケットのことはイーロン・マスクに任せて、自分たちは”Hello World”を表示させてみましょう。

そのために、まずconfig/urls.pyを以下のように編集します。

from django.contrib import admin
from django.urls import path, include # 追加

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("todo.urls")) # 追加
]

これはプロジェクトとアプリの繋ぎ込みです。

もしURLがlocalhost:8000/adminだったら、管理者サイトに遷移します。

その他の場合であれば、todoアプリのURL設定を参照するようになります。

URL設定のファイルはデフォルトで存在しません。
ゆえに自分でtodo/urls.pyを作成する必要があります。

以下のコマンドを入力するか、VSCode内でtodoフォルダ内に新しくurls.pyを作成しましょう。

$ touch todo/urls.py

あとは、この中にURLの設定を書いていくことになります。

Djangoのように大規模なフレームワークを使うと、自分が何をやっているのか、何をするべきなのか迷うことがあります。

でも、基本的に以下の流れだけおさえておけば大丈夫です。

  • アプリ内のviews.pyでロジックを作成し、
  • アプリ内のurls.pyでURLを設定する

“Hello World”の表示も、上記の手順でやってみます。

まずはtodoフォルダに入っているviews.pyで、以下のコードを書いてみましょう。

from django.shortcuts import render # 最初これだけ
from django.http import HttpResponse

# Create your views here.
def index(request):
    return HttpResponse("<h1>Hello World</h1>")

ここではindex()という関数が呼ばれたら、”Hello World”を返すHTTPレスポンスを作成しました。

あとはURLにアクセスしたとき、index()を呼び出せるようにすれば良いですね。

そこでurls.pyに以下のコードを追記します。

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index),
]

urlpatternsconfigフォルダ内でも使いました。URLの設定をするためのリストです。

path()の第一引数で""を指定しているので、
トップページにアクセスしたらviews.indexが呼び出される設定になっています。

つまりトップページにアクセスすると、”Hello World”が表示されるわけです。

本当に表示されるのか、確認してみましょう。

$ python manage.py runserver

サーバーを起動してみると、しっかり”Hello World”が表示されていますね!

STEP4 : モデルの作成とマイグレーションをおこなう

Todoアプリを作るためには、タスクを保存しておくデータベースが必要になります。

Djangoでは”Model”を定義することで、SQLを書かずともデータベースで使うテーブルを作成できます。

STEP4では、その具体的な手順を見ていきましょう。

  • models.pyでモデルを定義する
  • マイグレーションファイルを作成する
  • データベースにテーブルを作成する

順番に紹介していきます。

models.pyでモデルを定義する

todoフォルダ内のmodels.pyにModelを定義していきます。

タスクの登録には、まずタイトルを付けます。
さらに、タイトルだけでなくタスクの詳細も記入するようにしましょう。

ただし、内容によっては詳細がいらない場合もあるので、ブランクを許可することにします。

またタスクには締め切りを設けたいですね。

これらをmodels.pyに反映すると、以下のコードになります。

from django.db import models # 最初はこれだけ

# Create your models here.
class Todo(models.Model):
    title = models.CharField("タスク名", max_length=30)
    description = models.TextField("詳細", blank=True)
    deadline = models.DateField("締切")

    def __str__(self):
        return self.title

モデルフィールドの詳しい解説は省きます。
ぜひDjangoの公式ドキュメントを確認してみてください。

参考 : モデルフィールドリファレンス | Django ドキュメント | Django

マイグレーションファイルを作成する

models.pyで定義したモデルを、データベースのテーブルに反映していきます。

以下のコマンドを入力して、マイグレーションファイルを作成しましょう。

$ python manage.py makemigrations

コマンドの実行結果を見てみるとtodo/migrations/0001_initial.pyと書かれています。

この0001_initial.pyがマイグレーションファイルです。

データベースにテーブルを作成する

マイグレーションファイルを作成したら、その内容をデータベースのテーブルに反映します。

以下のコマンドを実行してみてください。

$ python manage.py migrate

各項目で”OK”が表示されていれば、データベースにテーブルを追加できています。

SQLを書かずにテーブルを作成できるなんて便利ですよね…!

これだけ簡単だど、本当にテーブルを作成できてるか気になります。
次のステップでは、テーブルを作成できたか確認し、そのあとでタスクを登録してみたいと思います。

STEP5 : 管理画面の設定とTodoタスクの登録

SQLを使えば、テーブルとその中身を確認できます。

でもここでは、Djangoで用意されている管理画面を使って、テーブルの確認とタスクの登録をやっていきます。

このステップで紹介するトピックは以下です。

  • SuperUserを作成して管理画面にログインする
  • Todoテーブルを管理画面で確認できるようにする
  • Todoデーブルにタスクを登録する

それでは順番に見ていきましょう。

SuperUserを作成して管理画面にログインする

“管理画面”というくらいなので、そもそもアプリを管理人が必要ですよね。

Djangoでは以下のコマンドを実行するだけで、管理者権限を持ったユーザー(=SuperUser)を作成できます。

$ python manage.py createsuperuser

途中でユーザー名、メールアドレス、パスワードを聞かれます。

自分の好きなユーザー名とパスワードを入力してください。
メールアドレスは必要ありません。エンターキーを押せばスキップできます。

SuperUserを作成できたら、管理者画面にログインしましょう。以下でサーバーを立ち上げます。

$ python manage.py runserver

トップページにアクセスすると、Hello Worldが表示されているはずです。
今回は管理者画面を使うので、http://localhost:8000/adminにアクセスします。

ここで、いま作成したアカウント名とパスワードを入力してください。

ログイン後に表示されたこのページでは、データベースに作成したテーブルを確認できます。

でもTodoテーブルが表示されていませんね…。

Todoテーブルを管理画面で確認できるようにする

作成したテーブルを管理画面で確認するには、
todoフォルダのadmin.pyに使用するモデルを登録する必要があります。

以下のコードを追加しましょう。

from django.contrib import admin
from .models import Todo

# Register your models here.
admin.site.register(Todo)

コードを保存したら、管理画面をリフレッシュします。

無事にTodoテーブルが表示されていますね!

Todoデーブルにタスクを登録する

適当にタスクを追加してみてください。
あとでタスクを追加する機能は作成しますが、先にトップページの表示を実装します。

STEP6 : Todoタスクを表示する | Read

それでは作成したタスクをトップページで表示してみましょう。

ここからはHTMLの編集もおこないます。
ゆえに「Djangoにおける機能開発の流れ」は以下になります。

  • アプリ内のviews.pyでロジックを作成し、
  • アプリ内のurls.pyでURLを設定する
  • そのあとHTMLファイルを書く

タスクの作成・表示・更新・削除、すべて上記の流れで開発していきます。

views.pyを編集してListViewを追加する

まずはviews.pyの編集からです。

view(ビュー)の編集には、以下の2パターンあります。

  • Class-Based Views
  • Function-Based Views

この記事では「Class-Based Views」を使っていきます。

作成したタスクを表示するためには、views.pyに以下のコードを追加してください。

from django.shortcuts import render
from django.views.generic import ListView

from .models import Todo


class TodoList(ListView):
    model = Todo
    context_object_name = "tasks"

このListViewを使うことで、タスクの表示が可能になります。

使用するモデルは、STEP4で作成したTodoです。
context_object_nameは、あとでHTMLに表示するとき使う変数名になります。

urls.pyを編集してルーティング設定する

“Hello World”を表示するために、index()を使っていました。

これをいま作成したTodoListに変更しましょう。

from django.urls import path
from .views import TodoList

urlpatterns = [
    path("", TodoList.as_view(), name="list"),
]

これでurls.pyの設定は完了です。

todo_list.htmlの作成と編集

サーバーを立ち上げてhttp://localhost:8000にアクセスしてみてください。

するとtodo_list.htmlが読み込めないというエラーが表示されるはずです。

というわけで、これから作っていきましょう。

HTMLを保存しておくフォルダは、todo/templates/todoです。
templatesの下にtodoを作成する必要があります。注意してください。

その中にtodo_list.htmlを作っていきます。
ターミナルを使えるなら、以下を実行しましょう。

$ mkdir -p todo/templates/todo
$ touch todo/templates/todo/todo_list.html

これで必要なフォルダとファイルが作成できました。

それでは試しに以下のHTMLを書いてみてください。

<h1>Todo List</h1>

保存したあとにサーバーを立ち上げます。
トップページにアクセスすると、”Todo List”と表示されていますね!

あとは作成したタスクを表示するだけです。
todo_list.htmlの中に、以下の内容を書いていきます。

<h1>Todo List</h1>

<table>
    <thead>
        <tr>
        <th scope="col">title</th>
        <th scope="col">deadline</th>
        </tr>
    </thead>
    <tbody>
    {% for task in tasks %}
    <tr>
        <td>{{ task.title }}</td>
        <td>{{ task.deadline }}</td>
    </tr>
    {% endfor %}
    </tbody>
</table>

テーブルタグを使ってタスクを表示しています。
ぜひサーバーを立ち上げて確認してみてください。

自分で作成したタスクが一覧で表示されているはずです。

STEP7 : Todoタスクの詳細を表示する | Read

トップページではタイトルだけ表示しました。
タスクの説明は、詳細ページで確認できるようにしましょう。

STEP7でも、やはり以下の流れで機能を開発していきます。

  • アプリ内のviews.pyでロジックを作成し、
  • アプリ内のurls.pyでURLを設定する
  • そのあとHTMLファイルを書く

まずはviews.pyからです。

views.pyを編集してDetailViewを追加する

詳細ページを作成するにはDetailViewを使います。

from django.shortcuts import render
from django.views.generic import ListView, DetailView

from .models import Todo


class TodoList(ListView):
    model = Todo
    context_object_name = "tasks"


class TodoDetail(DetailView):
    model = Todo
    context_object_name = "task"

上記のようにListViewの下に追加しましょう。

urls.pyを編集してルーティング設定する

次にURLの設定ですが、ここでは少し注意が必要になります。

タスクの一覧を表示するときは、""に設定すれば大丈夫でした。
でも今回設定する詳細ページは、「どのタスクの詳細を表示するのか」指定する必要があります。

つまり表示したいタスクに応じて、URLを変更する必要があるわけです。

そんなとき、どうすれば良いのかというと、タスクに割り振られているpk(=primary key)を指定します。

from django.urls import path
from .views import TodoDetail, TodoList, DetailView

urlpatterns = [
    path("", TodoList.as_view(), name="list"),
    path("detail/<int:pk>", TodoDetail.as_view(), name="detail"),
]

detail/<int:pk>と設定することで、各タスクごとに詳細ページを表示できます。

todo_detail.htmlの作成と編集

あとはHTMLを編集しましょう。

先にトップから詳細ページへ遷移できるようにしておきます。

<h1>Todo List</h1>


<table>
    <thead>
        <tr>
        <th scope="col">title</th>
        <th scope="col">deadline</th>
        </tr>
    </thead>
    <tbody>
    {% for task in tasks %}
    <tr>
        <td>{{ task.title }}</td>
        <td>{{ task.deadline }}</td>
        <td><a href="{% url 'detail' task.pk %}">詳細</a></td>
    </tr>
    {% endfor %}
    </tbody>
</table>

次にtodo_detail.htmlという名前で、詳細ページを表示するHTMLファイルを作成してください。

ファイルの中には、以下のコードを書いていきます。

<h1>Todo Detail</h1>

<div>
    <h2>{{task.title}}</h2>
    <p>{{task.deadline}}</p>
    <p>{{task.description}}</p>
</div>

これでタスクのタイトル、詳細な説明、締切日を確認できるようになります。

http://localhost:8000/detail/1にアクセスして、あなたが作成したタスクの詳細を見てみてください!

STEP8 : Todoタスクを作成する | Create

次はタスクを作成できる機能を開発しましょう。

  • アプリ内のviews.pyでロジックを作成し、
  • アプリ内のurls.pyでURLを設定する
  • そのあとHTMLファイルを書く

もちろんこの流れで進めていきます。

views.pyを編集してCreateViewを追加する

タスクを作成するにはCreateViewを使います。

from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView

from django.urls import reverse_lazy

from .models import Todo

# (中略)

class TodoCreate(CreateView):
    model = Todo
    fields = "__all__"
    success_url = reverse_lazy("list")

CreateViewでは、入力する項目をfieldsで設定する必要があります。
もちろん入力できる項目は、データベースで定義したカラムから選ぶことになります。

今回は、以下のカラムを設定していました。

  • title
  • description
  • deadline

これらの項目はすべて入力できるようにしたいので、__all__で全選択しているわけですね。

また、タスクの作成が完了したらreverse_lazy()を使ってlistという名前が付いたページに遷移させます。

urls.pyを編集してルーティング設定する

タスクの作成は以下のように設定すれば大丈夫ですね。

from django.urls import path
from .views import TodoDetail, TodoList, TodoCreate

urlpatterns = [
    path("", TodoList.as_view(), name="list"),
    path("detail/<int:pk>", TodoDetail.as_view(), name="detail"),
    path("create/", TodoCreate.as_view(), name="create"),
]

個別のタスクを選ぶ必要がないから、create/にアクセスすれば作成ページが表示されるように設定します。

todo_form.htmlの作成と編集

ここでサーバーを起動して、タスクの作成ページにアクセスしてみてください。「todo_form.htmlがないですよ」とエラーが表示されるはずです。

このエラーから分かるように、タスクの作成ページではtodo_create.htmlではなくtodo_form.htmlを準備する必要があります。

todo_form.htmlを作成したら、タスクを投稿するためのフォームを準備します。

<form action="" method="POST">{% csrf_token %}
    <table>
        {{ form.as_table }}
    </table>
    <input type="submit" value="送信">
</form>

これでタスクを作成するためのフォームが完成しました。
あとはトップページから、このフォームへアクセスできるようにtodo_list.htmlを編集します。

<h1>Todo List</h1>

<p><a href="{% url 'create' %}">新規作成</a></p>

<table>
<!-- (中略) -->
</table>

ファイルを保存したら、タスクを新規作成してみてください。
トップページに遷移して、作成したタスクが表示されているはずです。

STEP9 : Todoタスクを編集する | Update

間違えて作成したタスクを編集できる機能も開発しましょう。

いつもどおりviews.pyから編集していきます。

views.pyを編集してUpdateViewを追加する

タスクを編集するにはUpdateViewを使います。クラス内で書く内容はCreateViewと同じです。

from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView, UpdateView

from django.urls import reverse_lazy

from .models import Todo

# (中略)

class TodoUpdate(UpdateView):
    model = Todo
    fields = "__all__"
    success_url = reverse_lazy("list")

これをコードの一番下に追加してください。
なおタスクの作成と同様に、編集が完了したらトップページに遷移するよう設定しています。

urls.pyを編集してルーティング設定する

「タスクを編集する」ということは、個別のタスクを選択する必要があります。

つまり「STEP7 : タスクの詳細を表示する」と同じURL設定が必要になるわけです。

詳細ページのURL設定を参考にしながら、タスク編集のルーティングを設定していきます。

from django.urls import path
from .views import TodoDetail, TodoList, TodoCreate, TodoUpdate

urlpatterns = [
    path("", TodoList.as_view(), name="list"),
    path("detail/<int:pk>", TodoDetail.as_view(), name="detail"),
    path("create/", TodoCreate.as_view(), name="create"),
    path("update/<int:pk>", TodoUpdate.as_view(), name="update"),
]

これでURLの設定が完了しました。

todo_list.htmlの編集

いままでClass-Based Viewを使うときは、以下の3つをセットに実装していました。

  • アプリ内のviews.pyでロジックを作成し、
  • アプリ内のurls.pyでURLを設定する
  • そのあとHTMLファイルを書く

ですがタスクの編集では、HTMLファイルを書く必要がありません。
それはタスクの作成と同じHTML(=todo_form.html)を使いまわせるからです。

というわけで、トップページからタスクを編集できる設定だけやっておきます。

<h1>Todo List</h1>

<p><a href="{% url 'create' %}">新規作成</a></p>

<table>

    <!-- (中略) -->

    <tbody>
    {% for task in tasks %}
    <tr>
        <td>{{ task.title }}</td>
        <td>{{ task.deadline }}</td>
        <td><a href="{% url 'detail' task.pk %}">詳細</a></td>
        <td><a href="{% url 'update' task.pk %}">編集</a></td>
    </tr>
    {% endfor %}
    </tbody>
</table>

ファイルを保存したら、ぜひトップページから編集画面を開いてみてください。

タスクの作成と同じ画面が表示されるはずです。

STEP10 : Todoタスクを削除する | Delete

タスクの詳細、作成、編集まで完成しました。
最後にタスクを削除する機能を開発していきましょう。

views.pyを編集してDeleteViewを追加する

タスクを削除するにはDeleteViewを使います。

from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView

from django.urls import reverse_lazy

from .models import Todo

# (中略)

class TodoDelete(DeleteView):
    model = Todo
    context_object_name = "task"
    success_url = reverse_lazy("list")

クラスの中身は、これまでと同じですね。

urls.pyを編集してルーティング設定する

タスクを削除するページに遷移するには、詳細や編集のようにpk(=primary key)を使ってURLを設定します。

from django.urls import path
from .views import TodoDetail, TodoList, TodoCreate, TodoUpdate, TodoDelete

urlpatterns = [
    path("", TodoList.as_view(), name="list"),
    path("detail/<int:pk>", TodoDetail.as_view(), name="detail"),
    path("create/", TodoCreate.as_view(), name="create"),
    path("update/<int:pk>", TodoUpdate.as_view(), name="update"),
    path("delete/<int:pk>", TodoDelete.as_view(), name="delete"),
]

これでタスクを削除できるページのURL設定が完了しました。

todo_confirm_delete.htmlの作成と編集

あとはタスクを削除するためのHTMLを準備するだけです。

まずはtodo_list.htmlでタスクの削除ページへリンクを設定しておきましょう。

<h1>Todo List</h1>

<p><a href="{% url 'create' %}">新規作成</a></p>

<table>

    <!-- (中略) -->

    <tbody>
    {% for task in tasks %}
    <tr>
        <td>{{ task.title }}</td>
        <td>{{ task.deadline }}</td>
        <td><a href="{% url 'detail' task.pk %}">詳細</a></td>
        <td><a href="{% url 'update' task.pk %}">編集</a></td>
        <td><a href="{% url 'delete' task.pk %}">削除</a></td>
    </tr>
    {% endfor %}
    </tbody>
</table>

あとは削除ページのHTMLを書くだけです。
タスクを削除するからファイル名はtodo_delete.htmlにしたいところですよね。

ここでファイルを保存して、削除ページにアクセスしてみてください。
すると「todo_confirm_delete.htmlが読み込めない」とエラーが表示されます。

つまり、タスク削除ページのHTMLファイル名はtodo_confirm_delete.htmlである必要があります。

名前を間違えないようファイルを作成したら、以下の内容を記入します。

<h1>タスクの削除</h1>
<form action="" method="POST">{% csrf_token %}
    <p>{{task}}</p>
    <input type="submit" value="delete">
</form>

タスクの削除ではフォームの中身すべてを表示する必要はありません。

タイトルだけ分かれば良いので{{task}}としています。

ここまで書けたらサーバーを立ち上げてタスクを削除してみてください。
タスクの表示/作成/編集/削除と、すべての機能を開発できましたね!

これでTodoアプリは完成しました。
あとは見た目の問題なので、Djangoの使い方だけ知りたいなら以後は不要です。

もし見た目も整えていくなら、もう少しだけ頑張っていきましょう!

STEP11 : Djangoで作成したTodoアプリの見た目を整える

それでは最後にTodoアプリの見た目を整えていきましょう。

とは言っても、今回はゼロからCSSを書くことはしません。
誰でもサクッと良い感じの見た目に変更できるBootStrapを使っていきます。

参考 : Bootstrap · 世界で最も人気のあるフロントエンドフレームワーク

また、見た目を整えるために、新しいHTMLファイルを作成していきます。

base.htmlの作成

ターミナルを使えるなら以下のコマンド、そうでなければtemplates/todo/配下にbase.htmlを追加してください。

$ touch todo/templates/todo/base.html

ここで作成したbase.htmlは、ファイル名のとおりでベースになるHTMLを書いていきます。

どのページでも共通で使うHTMLはbase.htmlで記述して、このテンプレートを読み込むことで他のページも作成していきます。

というわけで、まずはベースになるHTMLを書いていきましょう。

base.htmlに以下のHTMLを記述していきます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo List</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
<body>
    {% block header %}
    {% endblock header %}

    {% block content %}
    {% endblock content %}
</body>
</html>

8行目はBootStrapを使うための設定です。

また<body></body>の中に書いた{% block header %}{% endblock header %}{% block content %}{% endblock content %}は、他のHTMLファイルでも使用します。

このタグの中に各ページ独特のコードを記入することで、HTMLテンプレートを拡張できる仕組みです。

テンプレートの拡張

それでは具体的にどうやって使うのか見ていきましょう。

todo_list.htmlを以下のように編集してみてください。

{% extends 'todo/base.html' %}

{% block header %}
<h1>Todo List</h1>
<p><a href="{% url 'create' %}">新規作成</a></p>
{% endblock header %}

{% block content %}
<table>
    <thead>
        <tr>
        <th scope="col">title</th>
        <th scope="col">deadline</th>
        </tr>
    </thead>
    <tbody>
    {% for task in tasks %}
    <tr>
        <td>{{ task.title }}</td>
        <td>{{ task.deadline }}</td>
        <td><a href="{% url 'detail' task.pk %}">詳細</a></td>
        <td><a href="{% url 'update' task.pk %}">編集</a></td>
        <td><a href="{% url 'delete' task.pk %}">削除</a></td>
    </tr>
    {% endfor %}
    </tbody>
</table>
{% endblock content %}

サーバーを立ち上げて、トップページにアクセスしてみましょう。

以前と少し見た目が違っていますよね。
見た目が変わる理由は、base.htmlで書いておいたBootStrapの設定が読み込まれているからです。

1行目で書いている{% extends 'todo/base.html' %}base.htmlを読み込んで、{% block header %}{% endblock header %}などのテンプレートタグ内にコードを書くことで中身を反映しています。

言い方を換えると{% block header %}{% endblock header %}{% block content %}{% endblock content %}にコードを書かないと、ページにHTMLが反映されません。

本来ならbase.htmlと同じように<head></head><body></body>を準備する必要がありますが、テンプレート拡張を使えばどのファイルでも共通して使うHTMLを使い回しできるわけですね!

base.htmlの編集

base.htmlとテンプレート拡張の仕組みが分かったら、あとはHTMLファイルを編集するだけです。

まずはbase.htmlにどのページでも共通して使うテンプレートを準備しておきましょう。

今回はGoogle Fontも使っていきます。
この記事ではOpen Sansを選んでいますが、ぜひ自分が好きなフォントを使ってみてください。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo List</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400&display=swap" rel="stylesheet">
    <style>
        body{
            padding-top: 20px;
            font-family: 'Open Sans', sans-serif;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="w-75 mx-auto">
            <div class="shadow-sm p-3 mb-5 bg-white rounded">
                {% block header %}
                {% endblock header %}
            </div>

            {% block content %}
            {% endblock content %}
        </div>
      </div>
</body>
</html>

これでbase.htmlの編集が完了しました。
このHTMLで使ったBootStrapのページは以下です。

参考 : Shadows(シャドウ) · Bootstrap v5.0

todo_list.htmlの編集

次にトップページを編集していきます。

{% extends 'todo/base.html' %}

{% block header %}
    <h1>Todo List</h1>
    <p>今日のタスクを作成しましょう!</p>
    <a class="btn btn-primary" href="{% url 'create' %}">新規作成</a>
{% endblock header %}

{% block content %}
<div class="shadow-sm p-3 mb-5 bg-white rounded">
    <table class="table">
        <thead>
            <tr>
            <th scope="col">タイトル</th>
            <th scope="col">締切日</th>
            <th scope="col"></th>
            </tr>
        </thead>
        <tbody>
        {% for task in tasks %}
        <tr>
            <td>{{ task.title }}</td>
            <td>{{ task.deadline }}</td>
            <td>
                <a href="{% url 'detail' task.pk %}">詳細</a>
                <a href="{% url 'update' task.pk %}">編集</a>
                <a href="{% url 'delete' task.pk %}">削除</a>
            </td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
</div>

{% endblock content %}

新規作成のページは青色で装飾してみました。
テーブルもBootStrapを使えば綺麗に表示できます。

参考 : Tables (テーブル) · Bootstrap v5.0

todo_form.htmlの編集

次にタスクの作成・編集ページです。

{% extends 'todo/base.html' %}

{% block header %}
<h1>タスクの作成/編集</h1>
{% endblock header %}

{% block content %}
<form action="" method="POST">{% csrf_token %}
    <table class="table">
        {{ form.as_table }}
    </table>
    <a class="btn btn-outline-secondary" href="{% url 'list' %}" role="button">戻る</a>
    <input class="btn btn-success" type="submit" value="送信">
</form>
{% endblock content %}

これくらいシンプルで良いと思います。
もちろん自分が好きなようにスタイルを当ててくださいね!

todo_detail.html

詳細ページでは、タスクの表示にカードを使ってみます。

{% extends 'todo/base.html' %}

{% block header %}
<h1>Todo Detail</h1>
{% endblock header %}

{% block content %}
<div class="card">
    <div class="card-body">
        <h2>{{task.title}}</h2>
        <p>{{task.description}}</p>
        <p><small class="text-muted">{{task.deadline}}</small></p>
    </div>
</div>
<a class="btn btn-outline-secondary mt-2" href="{% url 'list' %}" role="button">戻る</a>
{% endblock content %}

カードを使うと、まとまりがあって良いですね!

参考 : Cards (カード) · Bootstrap v5.0

todo_confirm_detail.html

最後に削除ページです。

{% extends 'todo/base.html' %}

{% block header %}
<h1>タスクの削除</h1>
{% endblock header %}

{% block content %}
<p>「{{task.title}}」を削除しますか?</p>
<form action="" method="POST">{% csrf_token %}
    <a class="btn btn-outline-secondary" href="{% url 'list' %}" role="button">戻る</a>
    <input class="btn btn-danger" type="submit" value="削除">
</form>
{% endblock content %}

ここではボタンだけ装飾しました。

サーバーを立ち上げてTodoアプリを確認する

これで簡単な装飾も完成しました。
ぜひサーバーを立ち上げてTodoアプリを確認してみてください。

はじめてのDjangoにしては上出来ではないでしょうか?

もしアプリをWeb上に公開したいなら、ぜひFlask編を確認してみてください。

あわせて読みたい
【保存版】30分でFlask入門!Webアプリの作り方をPythonエンジニアが解説 こんにちは、はやたす(@hayatasuuu )です。 この記事では「Flaskを使ったWebアプリ(Todoアプリ)の作り方」を分かりやすく紹介していきます。 Flaskの日本語情報は少な...

こちらで丁寧に解説しています。

まとめ : Django

というわけで、この記事ではDjangoでTodoアプリを開発する方法を紹介してきました。

今回は初心者向けだったので、ミニマムでWebアプリを作るための知識だけ書きました。

でも本当は、Djangoを使うと色々な機能を簡単に実装できます。

ぜひこれからも継続してDjangoを学習してみてください!

次に取り組むなら、こちらの書籍がおすすめです。

よかったらシェアしてね!
目次
閉じる