こんにちは、はやたす(@hayatasuuu )です。
この記事では「Djangoを使ってWebアプリ(Todoアプリ)を開発する方法」を分かりやすく紹介していきます。
Djangpの日本語情報は少ないので、この記事が間違いなく役立つはずです!
この記事を読めば、たとえPython初心者でも、Djangoを使って以下のようなWebアプリを開発できるようになりますよ。
元スクール講師であり、YouTubeで3.2万人以上、Udemyで2,000人以上にプログラミングを教えている僕が丁寧に解説していきます。
- ProgateレベルのPythonスキルがあること
- ProgateレベルのHTML/CSSスキルがあること
- VSCodeを操作できること
- (Nice to have)ターミナル操作・Linuxコマンドの知識
※完成したTodoアプリは以下に置いておきます!
本格的にDjangoを学びたい人へ
Udemyで「Django基礎マスターコース」を公開しました。
このコースを受講すれば、Djangoの基礎をマスターして、自分の好きなWebアプリを開発できるようになりますよ!
Djangoは国内・海外問わず採用する企業が多く、市場価値の高いスキルなので、今のうちに習得しておきましょう。
↓↓↓画像をクリックして「期間限定30%オフ」で購入する↓↓↓
参考 : 【知識ゼロからデプロイまで】 Django基礎マスターコース〜PythonでWebアプリを開発できるようになろう〜
独学に役立つLINE配信
Python独学のコツや役に立つ情報を配信するLINEアカウントを作りました!
いまなら学習に役立つ限定音声コンテンツ73本や、YouTubeで使えるソースコードをプレゼントしています。
無料で追加できるので、よかったら友達になってください!
\ 無料で使えるソースコードをプレゼント /
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),
]
urlpatterns
はconfig
フォルダ内でも使いました。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編を確認してみてください。
こちらで丁寧に解説しています。
まとめ : Django
というわけで、この記事ではDjangoでTodoアプリを開発する方法を紹介してきました。
今回は初心者向けだったので、ミニマムでWebアプリを作るための知識だけ書きました。
ですが、本当はDjangoを使うと、色々な機能をカンタンに実装できます。
Djangoをもっと学びたいと思ったら、ぜひUdemy講座でお会いしましょう!
↓↓↓画像をクリックして「期間限定30%オフ」で購入する↓↓↓
参考 : 【知識ゼロからデプロイまで】 Django基礎マスターコース〜PythonでWebアプリを開発できるようになろう〜