Todoアプリを作ろう(中級編)
ある程度プログラミングがわかるようになったけど、アプリケーションの作り方がわからないという声をいただいたのでこの記事を作ってみました。
プログラミング技術とフレームワークを組み合わせることで効率的にアプリケーションを開発できます。
今回はプログラミング技術を身につけるのに最適なTodoリストをDjangoで開発していきます。
(本サイトはアフィリエイト広告を利用しています)
Djangoとは?
Djangoの特徴
DjangoはPythonのWebアプリケーションフレームワークで、ウェブサイトやウェブアプリケーションを開発できます。
データベースの管理、URLのルーティング、テンプレートエンジンなどの多くの機能をプロジェクトを作成した段階で提供してくれるため、効率的にウェブアプリケーションを作成できます。
個人的にはFlaskのようなマイクロフレームワークでプロジェクトを作成して後から必要な機能(DBとの接続や認証機能など)を追加するよりもDjangoでプロジェクトを作成したときに揃っている方がアプリ開発しやすいです。
また、初心者の状態で必要な機能を選定するには時間がかかるし実装モレが出てきてしまう可能性もあるので、プロジェクト作成時点で必要な機能が揃うDjangoでアプリを開発するのがおすすめです。
DjangoでTodoアプリを作成する
Todoの全体図
Todoアプリは以下のようにプログラムが実行されます。
ユーザーがTodoアプリにアクセスするとプロジェクト_urls.pyがアプリ_urls.pyにアクセスします。
アプリ_urls.pyはアプリ_views.pyにアクセスします。
アプリ_views.pyは持ってくるデータを指定してアプリ_models.pyを経由してSQLiteから必要なデータを持ってきます。
持ってきたデータをアプリ_views.pyで処理してアプリ_templateに処理後のデータを渡します。
渡されたデータはアプリ_templateに適用されてユーザーのブラウザに表示されます。
仮想環境の構築
環境構築
デスクトップに「django-todo-app」フォルダを新規作成します。
「django-todo-app」フォルダをVSCodeで開きます。
「django-todo-app」フォルダで以下のコマンドを実行します。
~/django-todo-app % python3 -m venv .venv
仮想環境に入る
Macの場合
~/django-todo-app % source .venv/bin/activate
Windowsの場合
.venv\Scripts\activate.bat
以下のように「(.venv)」が表示されていれば仮想環境に入れています。
(.venv)~/django-todo-app %
必要なライブラリをインポートする
requirements.txtを作成して必要になるライブラリを書き込みます。
requirements.txt
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
asgiref==3.7.2
Django==4.2.4
sqlparse==0.4.4
typing_extensions==4.7.1
仮想環境に入ったままrequirements.txtに書かれてあるライブラリを読み込みます。
(.venv) ~/django-todo-app % python -m pip install -r requirements.txt
ライブラリを一つずつインポートするときは「pip install ライブラリ」でインストールできます。
アプリ開発_準備
Djangoでアプリ開発できるように準備します。
プロジェクトの作成
Djangoのコマンドでプロジェクトを作成します。
(.venv) ~/django-todo-app % django-admin startproject todo_project
アプリ(機能)を作成
作成したプロジェクトに移動して開発するアプリのフォルダを作成します。
(.venv) ~/django-todo-app % cd todo_project
(.venv) ~/todo_project % python manage.py startapp todo
「todo_project/todo_project/settings.py」の「INSTALLED_APPS」に以下のように追加することでプロジェクトとアプリの機能を紐付けます。
todo_project/todo_project/settings.py
---------------------------------------------------------------------------
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo' # アプリの機能を追加
]
設定言語を日本語に、タイムゾーンを東京にします。
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
これで準備は完了です。
以下のコマンドを実行してDjangoのアプリが立ち上がったら成功です。
(.venv) ~/todo_project % python manage.py runserver
アプリ開発(モデルの作成)
models.pyにデータの定義を書き込む
「todo_project/todo/models.py」に以下のように書き込みます。
todo_project/todo/models.py
---------------------------------------------------------------------------
from django.db import models
# Todoに入れるデータを定義する。
class TodoTask(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(blank=True,null=True)
completed = models.BooleanField(default=False)
def __str__(self) -> str:
return self.title
マイグレーションでアプリとDBに接続する
DBに反映させるためのPythonコードを生成します。
(.venv) todo_project % python manage.py makemigrations
生成されたPythonコードをDBに反映します。
(.venv) todo_project % python manage.py migrate
アプリ開発(ビューの作成)
「views.py」に機能を追加する
「todo_project/todo/views.py」に以下のように書き込みます。
todo_project/todo/views.py
---------------------------------------------------------------------------
from django.shortcuts import render, redirect, get_object_or_404
from .models import TodoTask
from .forms import TodoTaskForm
# Todoのリストを表示する機能
def todo_list(request):
tasks = TodoTask.objects.all()
return render(request, 'todo/todo_list.html', {'tasks': tasks})
# Todoを作成する機能
def todo_create(request):
if request.method == 'POST':
form = TodoTaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('todo_list')
else:
form = TodoTaskForm()
return render(request, 'todo/todo_form.html', {'form': form})
# Todoを更新する機構
def todo_update(request, pk):
task = get_object_or_404(TodoTask, pk=pk)
if request.method == 'POST':
form = TodoTaskForm(request.POST, instance=task)
if form.is_valid():
form.save()
return redirect('todo_list')
else:
form = TodoTaskForm(instance=task)
return render(request, 'todo/todo_form.html', {'form': form})
# Todoを削除する機能
def todo_delete(request, pk):
task = get_object_or_404(TodoTask, pk=pk)
if request.method == 'POST':
task.delete()
return redirect('todo_list')
return render(request, 'todo/todo_confirm_delete.html', {'task': task})
アプリ開発(フォームの作成)
「forms.py」にフォーム機能を追加する
「todo_project/todo/forms.py」に以下のように書き込みます。
todo_project/todo/forms.py
---------------------------------------------------------------------------
from django import forms
from .models import TodoTask
class TodoTaskForm(forms.ModelForm):
class Meta:
model = TodoTask
fields = ['title','description','completed']
アプリ開発(テンプレートの作成)
次はテンプレートを作成していきます。以下の場所にtemplatesフォルダを作成してHTMLを作成します。
todo_project/todo
「todo_list.html」にTodoリストを表示する
todo_list.htmlを作成して以下のコードを記載します。
todo_project/todo/templates/todo/todo_list.html
---------------------------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
<title>Todo List</title>
</head>
<body>
<h1>Todo List</h1>
<ul>
{% for task in tasks %}
<li>
{{ task.title }}
<a href="{% url 'todo_update' task.pk %}">Update</a>
<a href="{% url 'todo_delete' task.pk %}">Delete</a>
</li>
{% endfor %}
</ul>
<a href="{% url 'todo_create' %}">Create new task</a>
</body>
</html>
Bootstrapで装飾
<!DOCTYPE html>
<html>
<head>
<title>Todoリスト</title>
<!-- Bootstrap CSSリンクを追加 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
/* 取り消し線のスタイルを定義 */
.completed-task {
text-decoration: line-through;
}
</style>
</head>
<body>
<div class="container mt-5">
<h1 class="mb-4">Todoリスト</h1>
<div class="row">
{% for task in tasks %}
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title {% if task.completed %}completed-task{% endif %}">{{ task.title }}</h5>
<p class="card-text {% if task.completed %}completed-task{% endif %}">{{ task.description }}</p>
<div class="d-flex justify-content-between">
<a href="{% url 'todo_update' task.pk %}" class="btn btn-sm btn-primary">更新</a>
<a href="{% url 'todo_delete' task.pk %}" class="btn btn-sm btn-danger">削除</a>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<a href="{% url 'todo_create' %}" class="btn btn-primary mt-3">新しいタスクを作成</a>
</div>
<!-- Bootstrap JSとPopper.jsのリンクを追加 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
「todo_form.html」にTodoを送信するフォームを表示する
todo_form.htmlを作成して以下のコードを記載します。
todo_project/todo/templates/todo/todo_form.html
---------------------------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
<title>{% if form.instance.pk %}Update Todo{% else %}Create Todo{% endif %}</title>
</head>
<body>
<h1>{% if form.instance.pk %}Update Todo{% else %}Create Todo{% endif %}</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
</body>
</html>
Bootstrapで装飾
<!DOCTYPE html>
<html>
<head>
<title>{% if form.instance.pk %}Todoを更新{% else %}Todoを作成{% endif %}</title>
<!-- Add Bootstrap CSS link -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<div class="card">
<div class="card-body">
<h1 class="card-title">{% if form.instance.pk %}Todoを更新{% else %}Todoを作成{% endif %}</h1>
<form method="post">
{% csrf_token %}
<div class="mb-3 row">
<label for="{{ form.title.id_for_label }}" class="col-sm-2 col-form-label">タイトル</label>
<div class="col-sm-10">
{{ form.title }}
</div>
</div>
<div class="mb-3 row">
<label for="{{ form.description.id_for_label }}" class="col-sm-2 col-form-label">説明</label>
<div class="col-sm-10">
{{ form.description }}
</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" name="{{ form.completed.name }}"
id="{{ form.completed.id_for_label }}" {% if form.completed.value %}checked{% endif %}>
<label class="form-check-label" for="{{ form.completed.id_for_label }}">完了済み</label>
</div>
<div class="d-grid gap-2">
<input type="submit" value="Save" class="btn btn-primary">
</div>
</form>
</div>
</div>
</div>
<!-- Add Bootstrap JS and Popper.js links -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
「todo_confirm_delete.html」に削除の確認を表示する
todo_confirm_delete.htmlを作成して以下のコードを記載します。
todo_project/todo/templates/todo/todo_confirm_delete.html
---------------------------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
<title>Delete Todo</title>
</head>
<body>
<h1>Delete Todo</h1>
<p>Are you sure you want to delete "{{ task.title }}"?</p>
<form method="post">
{% csrf_token %}
<input type="submit" value="Delete">
</form>
</body>
</html>
Bootstrapで装飾
<!DOCTYPE html>
<html>
<head>
<title>Todoを削除</title>
<!-- Add Bootstrap CSS link -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h1>Todoを削除</h1>
<div class="card">
<div class="card-body">
<p class="card-text">「{{ task.title }}」を削除しますか?</p>
<form method="post">
{% csrf_token %}
<input type="submit" value="削除" class="btn btn-danger">
</form>
</div>
</div>
</div>
<!-- Add Bootstrap JS and Popper.js links -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
アプリ開発(ルートの作成)
アプリ(機能)のルートを設定
todoフォルダ直下にurls.pyを作成して以下のコードを記載します。
todo_project/todo/urls.py
---------------------------------------------------------------------------
from django.urls import path
from . import views
urlpatterns = [
path('', views.todo_list, name='todo_list'),
path('create/', views.todo_create, name='todo_create'),
path('update/<int:pk>/', views.todo_update, name='todo_update'),
path('delete/<int:pk>/', views.todo_delete, name='todo_delete'),
]
プロジェクトのルートを設定
todo_project/todo_projectフォルダ直下にあるurls.pyに
todo_project/todo_project/urls.py
---------------------------------------------------------------------------
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('todo/', include('todo.urls')),
]
アプリを起動
アプリを起動する
以下のコマンドを実行することでアプリが起動します。
(.venv) todo_project % python manage.py runserver
起動したら以下のurlにアクセスするとTodoアプリがブラウザに表示されます。
http://localhost:8000/todo/
もっと学びたい方へ
これまでTodoの機能を開発してきました。Djangoには認証やDB接続など様々な機能が始めからプロジェクトに追加されています。
この本では、Djangoの仕組みやDjangoで提供されている認証機能やDB接続の方法、ウェブアプリなどを図解でわかりやすく説明してくれています。
フレームワークを使用したことない方やPythonがある程度わかってきて何かアプリを作ってみたいと思っている方におすすめです。
詳細はこちら
まとめ
いかがでしたでしょうか?Djangoを使ってTodoアプリを作成する方法を紹介しました。Djangoはプロジェクトを作成した段階からさまざまな機能がセットで作成されているため部品を組み立てるようにアプリ開発ができてとても便利です。
自分でアプリを作れるようになると創造力や問題解決力が培われていくのでみなさんもアプリ開発に挑戦してみてはいかがでしょうか?
未経験からのITエンジニア
IT技術の進化速度が速くなっていっている今、IT技術にアンテナを張っておくことはとても重要です。エンジニアになろうとしている方やそうではない方もITスキルを磨くことで問題解決能力や論理的思考を養うことができます。複雑な課題に対処し、効果的な解決策を見つける能力はどの職種でも重宝されます。
そこで、エンジニア未経験の時にあったらよかったなと思っていた講座をマガジンにまとめました!アプリの基礎がわかるTodoアプリの開発からGit&GitHubでのチーム開発までエンジニアに必要な知識が詰まっています!
エンジニアリングの第一歩として使ってみてください!
「売上げアップに効果的」なキャッチコピーやテキストを作成してくれる国内最大級の「AIコピーライティングツール」
【Catchy】
会議・ミーティングの内容をリアルタイムで文字に起こすAI自動文字起こしサービス
【Notta】
ブログの記事制作にかかる時間を1/10で制作できる高品質SEO記事生成AIツール
【Value AI Writer byGMO】