Django の公式チュートリアル polls は冗長なので苦痛でした。
備忘録を兼ねて気楽なチュートリアルを作成しました。
実用的なことを短時間でひと通り見てみたい人向きです。
メモを書いたり編集したりする簡単なアプリが作れます。
コード部分をコピペして動かしてから中身を調べて下さい。
これが済んだら polls をもう少し楽に読めるかも。
2020-03-28 更新: windows10/Python-3.8.2-amd64/Django-3.0.4
2018-06-27: windows10/Python-3.6.5-amd64/Django-2.0.6
前作業
プロジェクトの作成
ソースを置きたい場所で以下を実行しプロジェクトを新規作成。
プロジェクト名は mysite だとする。※1
django-admin startproject mysite
作成したディレクトリ mysite に入ってアプリケーションを新規作成。
アプリケーション名は memo だとする。※2
cd mysite
python manage.py startapp memo
※1 プロジェクトとは大きく仕事をくくった単位(例えば「健康管理」)のこと。
※2 アプリケーションとはひとつひとつの仕事(例えば「体重記録」とか「ジョギング記録」)のこと。
ここまでのファイルの配置はこうなる
mysite/
mysite/
__pycashe__/ <- 気にしなくていい
setting.py, urls.py など *.py が 5 個
memo/
migrations/ <- 気にしなくていい
models.py, views.py など *.py が 6 個
manage.py <- プロジェクトの管理用
mysite/ の中に mysite/mysite/ というのがあって、ややこしい。
mysite/ は各アプリを含むプロジェクト全体を格納するフォルダ。
mysite/mysite/ は全アプリに共通する部分を保存するフォルダ。
プロジェクトを構成するアプリの登録
mysite/mysite/settings.py の INSTALLED_APPS を編集。
プロジェクト mysite の中にアプリケーション memo がある、と指定する。
settings.py は少しデカいのでの INSTALLED_APP のところの部分のみ記載。
あとは変更しない。
INSTALLED_APPS = [
'memo.apps.MemoConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
URL の設定
ブラウザで Web アプリケーションにアクセスするときの url を指定する。
mysite/mysite/urls.py を編集(コメントを除きファイル全体を掲載)
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('memo/', include('memo.urls')),
path('admin/', admin.site.urls),
]
mysite/memo/urls.py を新規作成(ファイル全体を掲載)
新たにファイルを作るとき、設置場所は注意が必要。
from django.urls import path
from . import views
urlpatterns = [
path('', views.MemoListView.as_view()),
path('index', views.MemoListView.as_view(),
name = 'site_index'),
path('create', views.MemoCreateView.as_view(),
name = 'site_create'),
path('detail/<int:pk>', views.MemoDetailView.as_view(),
name = 'site_detail'),
path('update/<int:pk>', views.MemoUpdateView.as_view(),
name = 'site_update'),
path('delete/<int:pk>', views.MemoDeleteView.as_view(),
name = 'site_delete'),
]
url を探すときは、まず最初に mysite/mysite/urls.py を参照する。
次に include された mysite/memo/urls.py も参照する、という順番。
参考(最初は分からなくても動きます)
- path の引数は path(UrlString, View, option)
- option のところで name に値を指定すると url の代わりにこの名前が使えるようになる。
- どれがどれだか混乱しないように、ちょっとくどい名前を付けた。
- as_view() はクラスビューの表示関数。
- pk は、django がそれぞれのメモに自動で付けたプライマリキー番号。
アプリケーション本体の作成
モデル、ビュー、テンプレートの 3 つを作ると、アプリケーションが作れる。
モデルの作成
「モデル」というのは、Web アプリが保持するデータ(例えば「日付」とか「体重」など)のこと。
単純なアプリなのでデータのフィールドは1つ(テキストで書いたメモ)だけ。
mysite/memo/models.py を修正(ファイル全体を掲載)
from django.db import models
class Memo(models.Model):
textfield = models.CharField(max_length = 200)
もっと複雑なデータの場合は、ここにデータのモデルを追加していくことになる。
ビューの作成
「ビュー」とはブラウザで表示するときの各ページのこと。ここでは、
- 全メモの一覧
- 新規メモ作成
- メモの詳細表示
- メモの編集
- メモの消去
の 5 つのページを作る。
mysite/memo/views.py を修正(ファイル全体を掲載)
from django.views import generic
from .models import Memo
class MemoListView(generic.ListView):
model = Memo
context_object_name = 'memo_context_list'
class MemoCreateView(generic.CreateView):
model = Memo
fields = ['textfield']
success_url = '/memo'
template_name = 'memo/memo_create.html'
class MemoDetailView(generic.DetailView):
model = Memo
template_name = 'memo/memo_detail.html'
context_object_name = 'memo_context'
class MemoUpdateView(generic.UpdateView):
model = Memo
fields = ['textfield']
success_url = '/memo'
template_name = 'memo/memo_update.html'
class MemoDeleteView(generic.DeleteView):
model = Memo
success_url = '/memo'
template_name = 'memo/memo_delete.html'
注意点
- generic.XxxView というのは「汎用ビュー」というもので、使いまわしができるように設計されたビュークラス。
- ブラウザに表示するときの体裁は、このあと説明する「テンプレート」で指定。
-
context_object_name
はコンテクスト(後述)の名前- 名前を指定しなければ
object_list
という名前がデフォルトで付けられる。 - django の汎用ビューシステムは、変数やファイルのデフォルト名が悪いのが欠点
- だから、あえて自分で名前を明示的に付けた。
- 名前を指定しなければ
-
template_name
はテンプレートファイルのファイル名- 明示的に指定しなければ、ビューごとに固有のデフォルトの名前が付けられる。
- デフォルト名が規則的でないし分かりにくいので、自分で分かりやすい名前を付けた。
- ファイル名を明示的に指定するときは、
memo/memo_delete.html
のようにディレクトリ名が必要
テンプレートの作成
フォルダ mysite/memo/templates/memo を新規作成し 5 つの html ファイルを新規作成。
テンプレートの html ファイルは、通常の html に django 用の文法が追加されている。
5 つの html ファイルは、5 つのビューにそれぞれ対応している。
フォルダ名は template ではなく templates で、最後に s が付いていることに注意。
・memo_list.html(ファイル全体を掲載)
ビュークラスはテンプレートにコンテクスト(操作用変数の塊みたいなもの)を送って表示させる。
memo_context_list
というのがコンテクストで views.py
で自分で名前を付けている。
temp
は、コンテクストからひとつずつ取り出した Memo オブジェクト。
<p>View : MemoListView</p>
<p>Template : memo_list.html</p>
{% if memo_context_list %}
<table>
{% for temp in memo_context_list %}
<tr>
<td><a href = "{% url 'site_detail' temp.pk %}"> {{ temp.textfield }}</a></td>
<td><a href = "{% url 'site_update' temp.pk %}">Edit</a></td>
<td><a href = "{% url 'site_delete' temp.pk %}">Delete</a></td>
</tr>
{% endfor %}
</table>
{% else %}
<p>No memo available.</p>
{% endif %}
<p><a href = "{% url 'site_create' %}">Create a new memo.</a></p>
・memo_create.html(ファイル全体を掲載)
フォームを扱う汎用ビューは、コンテクストではなく form オブジェクトをテンプレートに送る。
{{ form.textfield }}
のようにして中身のフィールドを取り出せるが、{{ form.as_p }}
と書く方がよく使われている。
as_p はフォームの中身を<p>でくくって列挙するというもので便利だが、ブラックボックスで中身が分かりにくいので、あえて使わなかった。
as_table といった書き方もある。
<p>View : MemoCreateView</p>
<p>Template : memo_create.html</p>
<form method = "post">
{% csrf_token %}
{{ form.textfield }}
<input type = "submit" value = "Create" />
</form>
・memo_detail.html(ファイル全体を掲載)
ビューから送られてくるコンテクストの名前は memo_context。
pk というのは、このメモのプライマリキー番号で、django が自動で割り振っている。
<p>View : MemoDetailView</p>
<p>Template : memo_detail.html</p>
{% if memo_context %}
<ul>
<li>Primary Key Number : {{ memo_context.pk }}</li>
<li>Memo Text : {{ memo_context.textfield }}</li>
</ul>
{% else %}
<p>No memo available.</p>
{% endif %}
<p><a href = "{% url 'site_index' %}">index</a></p>
・memo_update.html(ファイル全体を掲載)
<p>View : MemoUpdateView</p>
<p>Template : memo_update.html</p>
<form method = "post">
{% csrf_token %}
{{ form.textfield }}
<input type = "submit" value = "Save" />
</form>
・memo_delete.html(ファイル全体を掲載)
<p>View : MemoDeleteView</p>
<p>Template : memo_delete.html</p>
<form method = "post">
{% csrf_token %}
<input type= "submit" value = "Delete" />
</form>
ここまでのファイル配置はこうなる
mysite
├── mysite
│ ├── __pycashe__ <- 気にしなくていい
│ └── setting.py, urls.py など *.py が 5 個
├── memo
│ ├── migrations <- 気にしなくていい
│ ├── models.py, views.py などに urls.py を追加し *.py が 7 個
│ └── templates
│ └──memo
│ └── memo_list.html など *.html が 5 個
└── manage.py
参考(最初は分からなくても大丈夫)
- {{ varname }} は変数値を HTML に埋め込んでくれる
- {% if %}、{% endif %}、{% else %}、{{% for %}}、{{% endofor %}} は django テンプレート特有の文法
- 役割は想像のとおり
- {% crsf_token %} は、form に付け加えることで crsf 攻撃から守ってくれる呪文。
仕上げ
マイグレーションの実施
データベースへの保存の準備を行う。
マイグレーションするとデータベース (SQLite) に変更が反映される。
モデルを変更したりなど、大変更があるたびに実施が必要。
mysite/ で以下を実行。
python manage.py makemigrations
python manage.py migrate
動作の確認
mysite/ で以下を実行すると簡易 http サーバーが起動する。
python manage.py runserver
これでブラウザで見られるようになる。以下の URL で画面が出てきたら完成。
ポートはデフォルトで 8000 番なので注意。
http://localhost:8000/memo/