今回は「[Django初心者]DjangoでTodoリストを作成する」の第2回として、Todoの一覧表示まで一気にやっていきたいと思います。
前回はプロイジェクトを立ち上げ、ロケットを飛ばし、「settings.py」の編集まで行いました。
まだそこまでやれていない人はぜひ第1回をみてください。
GitHubはこちらです。
https://github.com/cardene777/todo
GitHubの使い方がわからない方はこちらの記事を参考にしてください!
https://www.cardenema.com/?p=687
それでは早速やっていきましょう!
現在の構成の確認
まずは前回まで作成てきたディレクトリの構成を確認しましょう。
├── 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
下記を押してください。
![](https://i0.wp.com/www.cardenema.com/wp-content/uploads/2021/02/Screen-Shot-2021-02-12-at-15.30.34-1024x598.png?resize=963%2C562&ssl=1)
このような画面が表示されていれば無事に開けています。
ではユーザー名に「test」とパスワードに「test」を入力して、ログインしていきましょう。
![](https://i0.wp.com/www.cardenema.com/wp-content/uploads/2021/02/Screen-Shot-2021-02-12-at-15.32.01-1024x383.jpg?resize=963%2C360&ssl=1)
このような画面が出てきたでしょうか?
「models.py」の「Meta」クラスで指定したように、「Todoリスト」と表示されていますね。
では「Todoリスト」をクリックしてみましょう。
![](https://i0.wp.com/www.cardenema.com/wp-content/uploads/2021/02/Screen-Shot-2021-02-12-at-15.33.51-1024x262.jpg?resize=963%2C246&ssl=1)
この画面が開かれるはずです。
ここからデータを追加したり、編集したり、削除することができます。
早速データを追加してみましょう。
![](https://i0.wp.com/www.cardenema.com/wp-content/uploads/2021/02/Screen-Shot-2021-02-12-at-15.35.33-1024x509.jpg?resize=963%2C479&ssl=1)
このように入力してみてください。
期日のところはカレンダーから押せるので楽ですよね!
入力できたら、保存を押しましょう。
![](https://i0.wp.com/www.cardenema.com/wp-content/uploads/2021/02/Screen-Shot-2021-02-12-at-15.36.37-1024x322.jpg?resize=963%2C303&ssl=1)
新たに作成できているのが確認できますね。
それではさらに2、3個追加していきましょう。
好きなように追加してください。
一覧表示の確認
データを登録できたことですし、そろそろ一覧表示ページをみてみましょう。
http://127.0.0.1:8000/todo/list/
こちらを開いてください。
![](https://i0.wp.com/www.cardenema.com/wp-content/uploads/2021/02/Screen-Shot-2021-02-12-at-15.42.55-1024x539.jpg?resize=963%2C507&ssl=1)
しっかりタイトルと期日が一覧表示されていますね。
ちなみに上のグレーの部分がジャンボトロンです。
最後に
今回は「DjnagoでTodoリストを作成する」の第2回として、Todoの一覧表示まで解説してきました。
続き...
質問などがあればコメントするか、下のアイコンからTwitterのDMまで送ってください!
それでは!