Djangoを用いた「TodoList」Webアプリ開発の手順


# 概要
Python3とDjango3を利用してToDoリストを作成します。
Djangoの汎用クラスビューを利用して、下記の基本的なCRUDの機能を実装します。

ToDoの一覧表示機能
ToDoの詳細表示機能
ToDoの作成機能
ToDoの編集機能
ToDoの削除機能

# 開発環境
開発環境は下記を利用しています。
Python 3.10.6
Django 4.1.5 (バージョン3.0と比べると機能が加わったくらいなので基本的な仕様は変わらない。)

# GitHub
サンプルのプログラムのリポジトリは下記のURLになります。
https://github.com/miyazaki-tsubasa/TodoListproject/tree/main/todoproject

# Djangoで作るToDoリスト
# 仮想環境の構築
下記のコマンドでpythonの仮想環境を構築。  
Pythonのバージョン確認
```
$ python3
```
バージョンが表示されたらok  

### プロジェクトを作成
todoprojectという名前のファイルを作成する。
```
tsuba_miya2345@ASUS01:~/work/todoproject$
```
上記になるように作成

### 仮想環境を作る
```
tsuba_miya2345@ASUS01:~/work/todoproject$ python3 -m venv venv
```
```
tsuba_miya2345@ASUS01:~/work/todoproject$ ls 
```
venvが作られていることを確認
```
tsuba_miya2345@ASUS01:~/work/todoproject$ source ~/venv/bin/activate
```
```
(venv)tsuba_miya2345@ASUS01:~/work/todoproject$
```
となる。

Djangoのインストール
下記のコマンドで仮想環境にDjangoをインストールしてください。
```
(venv)tsuba_miya2345@ASUS01:~/work/todoproject$ pip3 install django
```
# プロジェクトの作成
下記のコマンドでDjangoのプロジェクトを作成してください。
```
(venv)~$ python3 -m django startproject todoproject .
```
# todoアプリケーションの作成
todoアプリケーションを作成するため、下記のコマンドを実行してください。
```
$ python3 manage.py startapp todo
```
## todoアプリケーションの組み込み設定
mysite/settings.py を編集してtodoアプリケーションを組み込みます。
```
mysite/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'todo.apps.TodoConfig', #todoアプリケーションの組み込み
]
```
## todoアプリケーションのモデル作成
今回モデルは「タスクタイトル」,「メモ」,「優先度」,「項目削除」のシンプルな物を作成しました。

todo/models.py にて
```
from django.db import models

# Create your models here.

CHOICE = (('danger','high'),('warning','normal'),('primary','low'))

class TodoModel(models.Model):
    title = models.CharField(max_length=100)
    memo = models.TextField()
    priority = models.CharField(
        max_length=50,
        choices = CHOICE,
        null =True
     )
    duedate = models.DateField()

#管理画面のobjectの表示をタイトルと一致して表示
    def __str__(self):
        return self.title
```

## todoアプリケーションのビュー作成
ToDoの各機能に対応するようにDjangoの汎用クラスビューを利用してtodoアプリケーションのビューを作成します。

todo/views.py
```
todo/views.pyfrom django.shortcuts import render
from django.views.generic import ListView,DetailView,CreateView,DeleteView,UpdateView
from .models import TodoModel
from django.urls import reverse_lazy

# ToDoの一覧表示機能
class TodoList(ListView):
    template_name = 'list.html'
    model = TodoModel

# ToDoの詳細表示機能
class TodoDetail(DetailView):
    template_name = 'detail.html'
    model = TodoModel

# ToDoの作成機能
class TodoCreate(CreateView):
    template_name = 'create.html'
    model = TodoModel
    fields = ('title','memo','priority','duedate')
    success_url = reverse_lazy('list')

# ToDoの削除機能
class TodoDelete(DeleteView):
    template_name = 'delete.html'
    model = TodoModel
    success_url = reverse_lazy('list')

# ToDoの編集機能
class TodoUpdate(UpdateView):
    template_name = 'update.html'
    model = TodoModel
    fields = ('title','memo','priority','duedate')
    success_url = reverse_lazy('list')
```

### todoアプリケーションのURLを設定
まず、todo/でブラウザから接続された際、todoprojectのURL設定ではなく、todoアプリケーションのURL設定を参照するように記載を行います。


todoproject/urls.py
```
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('todo.urls')),
]
```

### todoアプリケーションに関するURL設定を下記ののように設定。

todo/urls.py
```
#from django.contrib import admin
from django.urls import path,include
from .views import TodoList,TodoDetail,TodoCreate,TodoDelete,TodoUpdate

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

]
```

### todoアプリケーションのテンプレート作成
まずは、テンプレート用のディレクトリを下記のようなに作成してください。
```
(venv) tsuba_miya2345@ASUS01:~/work/todoproject$ mkdir -p templates/todo
```

次に、htmlのベースとなるテンプレートを下記のように作成します。

todoproject/templates/base.html

```
<!doctype html>
<html lang="en">
 <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <title>Hello, world!</title>
  </head>
  <body>
    {% block header %}
    {% endblock header %}
    {% block content %}
    {% endblock content %}
</body>
</html>

```

### ToDoの一覧表示機能のためのテンプレートを下記のように作成。
todoproject/templates/todo/list.html

```
{% extends 'base.html' %}

{% block header %}
<div class="jumbotron jumbotron-fluid">
    <div class="container">
      <h1 class="display-4">TodoList</h1>
      <p class="lead">TodoListを作成して、生産的な毎日を過ごしましょう</p>
    </div>
  </div>{% endblock %}

{% block content %}
    <div class="container">
    <a href="{% url 'create'  %}" class="btn btn-secondary mb-2 " tabindex="-1" role="button" aria-disabled="true">新規作成画面へ</a>
    {% for item in object_list %}
    <div class="alert alert-{{ item.priority }}" role="alert">
        <p>{{ item.title }}  期日{{ item.duedate | date:"o/n/j "}}</p>
        <a href="{% url 'update' item.pk %}" class="btn btn-info " tabindex="-1" role="button" aria-disabled="true">編集画面へ</a>
        <a href="{% url 'delete' item.pk %}" class="btn btn-success " tabindex="-1" role="button" aria-disabled="true">削除画面へ</a>
        <a href="{% url 'detail' item.pk %}" class="btn btn-primary " tabindex="-1" role="button" aria-disabled="true">詳細画面へ</a>
    </div> 
 {% endfor %}
</div>
 {% endblock content %}

 ```

### Todoの新規作成機能のためのテンプレートを下記のように作成
todoproject/templates/todo/create.html
```
{% extends 'base.html' %}

{% block content %}
<form action = '' method = 'POST'>{% csrf_token %}
{{ form.as_p }}
<input type = 'submit' value = 'create'>
</form>
{% endblock content %}

```

### ToDoの詳細表示機能のためのテンプレートを下記のように作成。

todoproject/templates/todo/detail.html
```
{% extends 'base.html' %}

{% block header %}
<div class="alert alert-dark" role="alert">
    detail
</div>
{% endblock %}

{% block content %}
<div class="alert alert-success" role="alert">
    {{ object.title }}
</div>
<div class="alert alert-success" role="alert">
    {{ object.memo }}
</div>
{% endblock content %}
```

### ToDoの削除機能のためのテンプレートを下記のように作成。

todoproject/templates/todo/delete.html
```
{% extends 'base.html' %}
{% block content %}
<form action = '' method = 'POST'>{% csrf_token %}
<input type = 'submit' value = 'delete'>
</form>
{% endblock content %}
```
### ToDoの更新機能のためのテンペレートを下記のように作成
todoproject/templates/todo/update.html
```
{% extends 'base.html' %}

{% block content %}
<form action = '' method = 'POST'>{% csrf_token %}
{{ form.title }}
{{ form.memo }}
{{ form.priority }}
{{ form.duedate }}
<input type = 'submit' value = 'update'>
</form>
{% endblock content %}
```

# todoアプリケーションのマイグレーション
データベースにtodoアプリケーション用のテーブルを作成するために、下記のコマンドを実行してください。
```
(venv) tsuba_miya2345@ASUS01:~/work/todoproject $ python3 manage.py makemigrations
```
```
(venv) tsuba_miya2345@ASUS01:~/work/todoproject$ python3 manage.py migrate
```

# アプリケーションの動作確認
プログラムが完成しましたので、アプリケーションの動作確認を行う。
下記のコマンドでDjangoサーバを起動。
```
(venv) tsuba_miya2345@ASUS01:~/work/todoproject$ python3 manage.py runserver
```

ブラウザを起動し、下記のURLにアクセスする。
http://127.0.0.1:8080/todo/list/
成功すると下記のようなアプリケーションが表示される。

![スクリーンショット_20230112_160927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852567/bf32fce9-cfc0-c892-2a48-86cdf727d003.png)

上記の例は
実際に新規作成をしてタスクを作成した例。