Django Python

[Django初心者]DjangoでTodoリストを作成する②

今回は「[Django初心者]DjangoでTodoリストを作成する」の第2回として、Todoの一覧表示まで一気にやっていきたいと思います。

前回はプロイジェクトを立ち上げ、ロケットを飛ばし、「settings.py」の編集まで行いました。

まだそこまでやれていない人はぜひ第1回をみてください。

GitHubはこちらです。

GitHubの使い方がわからない方はこちらの記事を参考にしてください!

それでは早速やっていきましょう!

現在の構成の確認

まずは前回まで作成てきたディレクトリの構成を確認しましょう。

├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
└── manage.py

todo」ディレクトリの配下がこのようになっていれば、まずは大丈夫です。どこか違う方は第1回を見直すか、コメントに書き込むか、TwitterでDMを送ってください!

アプリケーションの作成

 todoを作成したり、編集したり、削除したり、一覧表示するために、アプリケーションを作成しましょう。

ターミナルを開いてください。

# todoディレクトリの配下で以下を実行してください。
python manage.py startapp todo

そうすると全体の構成が次のようになるはずです。

├── config
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   └── settings.cpython-36.pyc
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
└── todo
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py

これでアプリケーションの作成は完了です。

アプリケーションのつなぎこみ

アプリケーションの作成ができたので、次にアプリケーションとプロジェクトのつなぎ込みをしていきましょう。

これを行わないと、いくらアプリケーションを作り込んでも表示されることができません。

settings.py

まずは「settings.py」から追記していきましょう。

# 34行目あたりのINSTALLED_APPSに追記します。
INSTALLED_APPS = [
    'todo.apps.TodoConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

これでDjango側にtodoアプリケーションの登録を行うことができました。

ちょっと見慣れないと思いますが、これで登録ができるという理解で大丈夫です。

urls.py

次に「urls.py」にURLのつなぎ込みをしていきます。

これをすることで、ページが表示されるようになります。

from django.contrib import admin
from django.urls import path, include

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

これでtodoアプリケーションへのつなぎ込みが完了です。

モデルの作成

ここからtodoアプリケーションの中身を作っていきます。

まずは「models.py」から作成していきましょう。

models.py」では、データベースにどのようなデータを登録するかのフォーマットを定義しています。

わかりやすく具体例で説明すると、Todoリストには「タイトル、内容、期日」、などを登録する必要があります。

しかし、そのためのフィールドがどこにも用意されていないので、「models.py」でそれを作成しましょう!というイメージです。

解説はここまでにして早速作っていきましょう。

次のように「models.py」を書き換えてください。

from django.db import models
from django.utils import timezone


class TodoModel(models.Model):
    class Meta:
        verbose_name = "Todoリスト"
        verbose_name_plural = 'Todoリスト'

    title = models.CharField(
        verbose_name="タイトル",
        max_length=50,
    )
    content = models.TextField(
        verbose_name="内容"
    )
    deadline = models.DateTimeField(
        verbose_name="期日",
        default=timezone.now
    )

    def __str__(self):
        return self.title

見慣れない部分が多いと思うので、1つずつ説明してきますね。

from django.db import models
from django.utils import timezone

ここでは、Django側に用意されている、「models」と「timezone」というものをインポートしています。

models」はモデルを作成する上で必要になるものです。

timezone」は時刻を扱うときに必要なものです。

class TodoModel(models.Model):
    class Meta:
        verbose_name = "Todoリスト"
        verbose_name_plural = 'Todoリスト'

TodoModelというクラスを定義しています。

先ほどインポートしてきた「models」から「Model」というものを継承しています。

継承についてはこちらの記事を参考にしください。

そして、「Meta」というクラスも定義しています。

これは後々出てくる管理画面での表示を見やすくしてくれます。

verbose_name」では、指定した名前に「s」がついた状態で管理画面に表示されます。

今回の場合では「Todoリストs」ですね。

この「s」はいらないので、「verbose_name_plural」を指定することで、「s」が外れた状態で表示されます。

詳しくはこちらを参考にしてください。

title = models.CharField(
        verbose_name="タイトル",
        max_length=50,
    )
content = models.TextField(
    verbose_name="内容",
    )
deadline = models.DateTimeField(
    verbose_name="期日",
    default=timezone.now,
    )

ここでは具体的なフィールドを定義しています。

こちらでも「verbose_name」が使用れていますね。

役割は先ほどと似ていて、管理画面での表示を見やすくしてくれます。

こちらでは「s」がつかないので、「verbose_name」のみで問題ないです。

CharField」では、文字列を入力することができます。

そして、「max_length」を指定して、文字数の上限を設定できます。(必須の引数なので、設定し忘れに注意してください。)

TextField」では、文字数制限なく文字を入力することができます。

DateTimeField」では、日時を入力できます。このフィールドの利点としては、カレンダーから選択できるということが挙げられます。(後々管理画面のところでお見せします。)

def __str__(self):
    return self.title

最後の部分ですね。

こちらも管理画面での表示関係のもので、管理画面の一覧部分で表示するものを設定できます。

これで一通り「models.py」の説明ができたので、次に移りたいと思います。

urls.pyの作成

先ほど「config」配下の「urls.py」を編集しましたが、次はアプリケーションの「urls.py」を編集していきます。

アプリケーション側にはデフォルトで「urls.py」が用意されていないので自分で作成してください。

アプリケーションの方には最初っから「urls.py」がないので、自分で作成する必要があります。

ターミナルのtodoアプリケーションディレクトリで次のようにコマンドを打ってください。

touch urls.py

一応全体の構成を確認しておきましょう。

├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
└── todo
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    ├── urls.py
    └── views.py

追加されているのが確認できますね。

それでは編集していきましょう。

from django.urls import path
from .views import TodoList

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

大まかな部分は「config」の「urls.py」と変わりませんが、一応説明します。

from django.urls import path
from .views import TodoList

1行目でDjnagoにある「urls」から「path」というものをインポートして、URLのつなぎ込みができるようにしてあります。

2行目では、同じ改造にある「view.py」から「TodoList」というクラスを読み込んでいます。

注意点として、この「TodoList」というクラスはまだ作成していません。

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

この「urlpatterns」でURLの設定ができます。

'list/'」というURLに入力されればこの部分が呼び出されます。

呼び出された後は、「TodoList」という「view.py」にあるクラスが呼び出されます。(繰り返しになりますが、まだ「TodoList」クラスは作成していません。)

最後の「name='list'」はHTMLファイルで呼び出す際に使われます。

view.pyの編集

次に「views.py」を編集していきます。

下記のように編集してください。

from django.views import generic
from .models import TodoModel


class TodoList(generic.ListView):
    template_name = 'todo/list.html'
    model = TodoModel

こちらも1つずつ解説していきます。

from django.views import generic
from .models import TodoModel

1行目でDjangoに用意されている、「views」の「generic」というものをインポートします。

これを使用することで簡単に「view.py」が作成できるので、必須アイテムです。

2行目で先ほど作成した「TodoModel」を読み込んでいます。

class TodoList(generic.ListView):
    template_name = 'todo/list.html'
    model = TodoModel

これは先ほど「urls.py」で読み込んでいた、TodoListクラスです。

generic」から「ListView」を読み込むと、モデルに登録されているデータを一覧表示することができます。

template_name」は、この「views.py」のTodoListが呼び出された時に表示されるHTMLファイルを指定します。

model」は一覧表示したいモデルを選択します。

今回は1つしかモデルは作成していませんが、複数作成することもできます。

HTMLファイルの作成

ではいよいよ表示するページを作成していきましょう。

Djangoでは「base.html」というものを作成して、他のHTMLファイルは「base.html」を拡張していくというように作成していきます。

そのため、まずは「base.html」を作成していきましょう。

ターミナルで次のようにコマンドを打ってください。

mkdir templates && cd templates && touch base.html && cd ../ 

なんか見慣れないコードですが、やっていることは下記と同じです。

mkdir templates
cd templates
touch base.html
cd ../ 

1行で書いた方が楽なので、 1行で書きましたが、好きな方を使用してください。

一応全体の構成を確認しておきます。

├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
├── templates
│   └── base.html
└── todo
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    ├── urls.py
    └── views.py

templates」ディレクトリと「base.html」がその配下に作成されていますね。

では次に「list.html」をtodoアプリケーション配下に作成していきましょう。

cd todo
mkdir templates
cd templates
mkdir todo
cd todo
touch list.html

# 1行で書く場合
cd todo && mkdir templates && cd templates && mkdir todo && cd todo && touch list.html

全体の構成を確認しましょう。

├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
├── templates
│   └── base.html
└── todo
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── templates
    │   └── todo
    │       └── list.html
    ├── tests.py
    ├── urls.py
    └── views.py

todoアプリケーションの配下に「templates」ディレクトリがあり、その配下にtodoディレクトリがあり、その配下に「list.html」があるのが確認できますね。

では早速HTMLファイルを編集していきましょう。

base.html

{% load static %}
<html lang="ja">
  <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://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

    {% block header %}
    {% endblock header %}
    <title>Todo App</title>
  </head>
  <body>
    {% block content %}
    {% endblock content %}

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
  </body>
</html>

ここではBootstrapを読み込んでいます。

BootstrapはCSSのフレームワークで、簡単におしゃれなサイトを作ることができます。

ここで「{% block content %}{% endblock content %}」に関する説明をしていきます。

そもそも「base.html」を作成する理由は、コードの冗長性をなくすためです。

HTMLファイルはどのファイルにも共通して記述されるものがあります。

そのため、その記述を1つのファイルにまとめて、そのファイルを拡張していけば楽じゃね?という考えです。

そしてその拡張する場所がここです。

{% block content %}
{% endblock content %}

この2行の間に記述することで、「base.html」に書かれていることをベースに新たなHTMLファイルを作成することができます。

ちなみに1行目の「{% load static %}」はCSSファイルや画像ファイルを読み込む際に必要なものです。

list.html

ここにはモデルに登録されているデータを一覧表示するためのコードを書いていきます。

下記のように編集してください。

{% extends 'base.html' %}
{% load static %}

{% block header %}
<link rel="stylesheet" href="{% static 'todo/css/list.css' %}">
{% endblock header %}

{% block content %}
<div class="jumbotron jumbotron-fluid">
    <div class="container">
        <h1 class="display-4">TodoList</h1>
        <p class="lead">やることを記入しましょう</p>
    </div>
</div>
<div class="container ">
    {% for list in object_list %}
        <div class="one_box">
            <h1>{{ list.title }}</h1>
            <h4>{{ list.deadline }}</h4>
        </div>
    <hr>
    {% endfor %}
</div>
{% endblock content %}

こちらも1つずつ説明していきます。

{% extends 'base.html' %}
{% load static %}

1行目で、先ほど作成した「base.html」を読み込んでいます。(extendsとあるように拡張していますね。)

2行目は先ほど説明したように、CSSファイルや画像ファイルを読み込む際に必要なものです。

{% block header %}
<link rel="stylesheet" href="{% static 'todo/css/list.css' %}">
{% endblock header %}

ここではCSSファイルを読み込んでいます。

base.html」を見ればわかりますが、hrader部分に読み込まれていることがわかります。

<div class="jumbotron jumbotron-fluid">
    <div class="container">
        <h1 class="display-4">TodoList</h1>
        <p class="lead">やることを記入しましょう</p>
    </div>
</div>

これはBootstrapのジャンボトロンというものです。

どういうものかは、後でページを表示した時に確認しましょう。

<div class="container ">
    {% for list in object_list %}
        <div class="one_box">
            <h1>{{ list.title }}</h1>
            <h4>{{ list.deadline }}</h4>
        </div>
    <hr>
    {% endfor %}
</div>

ここでモデルの登録されているデータを一覧表示しています。

for文はpythonのコードなので理解しやすいはずです。

ここでは、タイトルと期日を一覧表示させます。

objecy_list」というのは、モデルの一覧が格納されているものだと認識してください。

ここの名前を変更することもできますが、それはおいおいやるとしましょう。

{% block content %}
{% endblock content %}

上記で囲むことで、bodyに読み込まれることが確認できます。

CSSファイルの編集

まずはcssファイルを作成していきましょう。

cd todo
mkdir static
cd static
mkdir todo
cd todo
mkdir css
cd css
touch list.css

# 1行で書く場合
cd todo && mkdir static && cd static && mkdir todo && cd todo && mkdir css && cd css && touch list.css

全体の構成も確認しておきましょう。

├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
├── templates
│   └── base.html
└── todo
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── static
    │   └── todo
    │       └── css
    │           └── list.css
    ├── templates
    │   └── todo
    │       └── list.html
    ├── tests.py
    ├── urls.py
    └── views.py

しっかり作成できていますね。

では編集していきましょう。

.new-btn{
    margin-bottom: 3rem;
    margin-top: 3rem;
}

.btn-content{
    margin: 1rem;
}

.btns{
    display: flex;

}

説明は今回は省かせていただきます。

管理画面にログイン

ここでは管理画面にログインして、Todoをいくつか登録していきます。

管理ユーザーの作成

管理画面にログインするには管理ユーザーを作成捨必要があります。

ターミナルで以下のようにコマンドを実行してください。

python manage.py createsuperuser

このコマンドを打つと色々聞かれるので、次のように入力してください。

ユーザー名 (leave blank to use '~'): test
メールアドレス: 何も入力せずにEnterキーを押してください。
Password: test
Password (again): test
このパスワードは ユーザー名 と似すぎています。
このパスワードは短すぎます。最低 8 文字以上必要です。
このパスワードは一般的すぎます。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

ちなみにpassword入力時は入力しても表示はされないので、慌てないでください。

管理画面にモデルを表示するための設定

管理画面にモデルの内容を表示するには、todoアプリケーションの「admin.py」を編集する必要があります。

admin.py」を編集する必要があります。

admin.py」を次のように編集してください。

from django.contrib import admin
from todo.models import TodoModel

admin.site.register(TodoModel)

このように登録すると覚えておく程度の理解で問題ないです。

管理画面にログイン

早速ログインしてきましょう。

ターミナルで次を実行してください。

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

下記を押してください。

このような画面が表示されていれば無事に開けています。

ではユーザー名に「test」とパスワードに「test」を入力して、ログインしていきましょう。

このような画面が出てきたでしょうか?

models.py」の「Meta」クラスで指定したように、「Todoリスト」と表示されていますね。

では「Todoリスト」をクリックしてみましょう。

この画面が開かれるはずです。

ここからデータを追加したり、編集したり、削除することができます。

早速データを追加してみましょう。

このように入力してみてください。

期日のところはカレンダーから押せるので楽ですよね!

入力できたら、保存を押しましょう。

新たに作成できているのが確認できますね。

それではさらに2、3個追加していきましょう。

好きなように追加してください。

一覧表示の確認

データを登録できたことですし、そろそろ一覧表示ページをみてみましょう。

こちらを開いてください。

しっかりタイトルと期日が一覧表示されていますね。

ちなみに上のグレーの部分がジャンボトロンです。

最後に

今回は「DjnagoでTodoリストを作成する」の第2回として、Todoの一覧表示まで解説してきました。

続き...

質問などがあればコメントするか、下のアイコンからTwitterのDMまで送ってください!

それでは!

-Django, Python
-,