Django公式のチュートリアル「Writing your first Django app, part 2」を元に進んでいきます。
チュートリアル – その2では、以下の内容を学びます。
- データベース
- モデル
- shell
- 管理者用のadmin(アドミン)ページ
app1 $ source myenv/bin/activate
(myenv) app1 $ cd mysite
(myenv) mysite $
データベースについて
データベースとは、色んな情報の集まりの事を言います。エクセルの様なものをイメージしてもらえば良いと思います。さらに、そのデータベースを管理するシステムがいくつかあります。
- SQLite(エスキューライト)
- MySQL(マイエスキューエル)
- PostgreSQL(ポストグレスキューエル)
- etc…
これらはDBMS(データベース管理システム)といい、単に「データベース」と言ったりもします。種類を覚える必要はないので安心してください。
Djangoには、元々pythonに組み込まれているSQLiteがデフォルトで設定されています。
作ったアプリを公開する場合は、何のデータベースを使うか予め設定する必要がありますが、これにはサーバーの知識が必要なので、今は気にせずデフォルトのSQLiteを使ってください。何の設定も必要ありません。
プロジェクトの基本設定
settings.pyの以下3つの設定は、プロジェクトを日本用にするものなので、プロジェクトを作成した時は必ず設定します。
- IINSTALLED_APPS(インストールド・アップズ)
- LANGUAGE_CODE(ランゲージ・コード)
- TIME_ZONE(タイムゾーン)
mysiteディレクトリにあるsettings.pyで以下の内容を追加・修正し保存してください。
# 33行目くらい
INSTALLED_APPS = [
'polls', # 作成したアプリを追加
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
# 106行目くらい
LANGUAGE_CODE = 'ja' # 日本語に変更
# 108行目くらい
TIME_ZONE = 'Asia/Tokyo' # アジア/東京に変更
データベースにテーブルを作る
テーブルは表という意味です。Djangoではターミナルでコマンドを実行するだけで、model(モデル)を元にデータベースにテーブルを作成してくれます。
pollsのmodels.pyに以下の内容を記入し保存します。
from django.db import models
# 質問のモデル
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
# 選択肢のモデル
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
モデルの説明
# モデルを定義する時はこの形で始まります。
class モデル名(models.Model):
# フィールドの定義は以下の形で定義します。(インデントを忘れないように)
変数 = models.フィールドの種類(引数)
# 以下を日本語にすると
question_text = models.CharField(max_length=200)
名前は「question_text」とし、文字列を保存するための場所(CharField)とします。最大200文字とします。
変数
pythonで変数は代入を意味します。x = 1であれば、xに1を代入するという意味でxが1として扱われます。変数は必ず英語にしましょう。
ローマ字書きは基本NGです。例えば、名前のフィールドを作るのであれば、「namae」ではなく「name」にします。
フィールドの種類
何を保存する場所(フィールド)なのか設定します。
フィールドの種類は、日時を入力するフィールドや、数字を入力するフィールド、画像を保存するフィールド、他のテーブルと紐付けるフィールドなど沢山あります。
良く使うフィールドは大体決まっているので全てを覚える必要はありません。使ったことがあるフィールドを一つずつ覚えていきましょう。(フィールドの種類一覧(公式))
引数(ひきすう)
カッコの中身を引数と言います。オプション設定のようなものです。
上記では「max_length=200」が引数に指定されているので、最大文字数が200文字となります。
フィールドの種類によって、必須の項目があったり、設定できる内容が変わるという事だけ覚えておいて下さい。ちなみに、CharField(キャラ・フィールド)にはmax_lengthの引数が必須です。
modelに書いた内容を元に、下記のテーブルがデータベースに作成されることになります。
中身はまだ何も入っていないので????としています。
Questionモデル
id | question_text | pub_date |
1 | ???? | ???? |
Choiceモデル
id | question | choice_text | votes |
1 | ???? | ???? | ???? |
気づいた方もいるかもしれませんが、idのフィールドを設定していないのにidの列が作られていますね!
idは一意でなければならない(テーブルに一つしか存在してはいけない)ので、Djangoが自動で設定してくれます。
さっそくデータベースに反映させていきましょう!
「python manage.py makemigrations アプリ名」で、データベースにmigrate(移行)するためのファイルを作成します。これをマイグレーションファイルと言います。
以下のコマンドでマイグレーションファイルを作成してください。
$ python manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
上記のような表示がでたら成功です!
エラーが出た場合は、内容をコピーして翻訳してみましょう。多分、models.pyかsettings.pyのコードに間違いや記入漏れがあります。
このコマンドはアプリ名を入れなくても実行できますが、その場合は全てのアプリのマイグレーションファイルが作られます。
次のコマンドを実行すると、マイグレーションファイルを元にデータベースにテーブルが作成されます。
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying polls.0001_initial... OK
Applying sessions.0001_initial... OK
長いですが、OKがいっぱいでたと思います。
これで無事、データベースにテーブルが作成されました。
重要
モデルとマイグレーションファイルとデータベースの構造は、等しい必要があります。
マイグレーションファイルを変更したりすると、テーブルとの情報が一致しなくなるのでエラーが発生します。
モデルのフィールドを作成・追加・変更・削除した場合は、必ずmakemigrations → migrateの順で行って下さい。
テーブルにデータを入れてみる
今QuestionにもChoiceにも何もデータが入っていない状態ですが、中身を確認してみましょう。
以下のコマンドでshell(シェル)を起動させます。
shellは書いたコードの結果をリアルタイムで出力してくれます。
$ python manage.py shell
するとこんな表示になったと思います。
Python 3.9.1 (default, Aug 24 2022, 23:01:31)
[Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
shellを起動している時は、先頭に「>>>」が付きます。
下に記載した>>>の行のコードを、一行ずつコピペし実行してみてください。(>>>はコピーしない)
コード内に#で解説していますが、この部分はメモなので入力しなくてOKです。
# pollsモデルから、QuestionとChoiceを読み込みます。
>>> from polls.models import Question, Choice
# Questionのデータ(オブジェクト)を全て取得
>>> Question.objects.all()
<QuerySet []> # 何も入ってないので空のリストが返されます。
# timezoneを扱えるように読み込みます
>>> from django.utils import timezone
# Questionモデルの、question_textが「What's new?」で、pub_dateが「今の時間」のデータを、qとします。
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# qをQuestionのテーブルに保存します
>>> q.save()
# qのidを取得
>>> q.id
1
# qのquestion_textを取得
>>> q.question_text
"What's new?"
# qのpub_dateを取得
>>> q.pub_date
datetime.datetime(2022, 9, 4, 22, 31, 25, 364779, tzinfo=datetime.timezone.utc)
# qのquestion_textに「"What's up?"」を代入します。
>>> q.question_text = "What's up?"
# qをデータベースに保存します。
>>> q.save()
# qのquestion_textを取得
>>> q.question_text
"What's up?"
# Questionのデータ(オブジェクト)を全て取得
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
お疲れ様です。ちょっと面倒くさかったでしょう?
通常、こういったデータベースの操作はviews.pyに書いて処理します。
そしてもう一つ、最後の行は「Question object (1)」と書かれていて中身が分からないですね・・・
この問題はモデルの設定で解決できるので、models.pyで次の内容を追記し保存してください。
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self): # このブロックを追加
return self.question_text
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self): # このブロックを追加
return self.choice_text
モデルに「def __str __ (self):」を設定することで、出力の結果が「question_text」の内容になります。アンダーバーはstrの前後に2つずつです。
shellを再起動してもう一度試してみましょう。
「control + D」でshellを終了し、「python manage.py shell」で起動。
# QuestionとChoiceをimportする
>>> from polls.models import Question, Choice
# Questionの全てのオブジェクトを取得
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
「What’s up?」と表示されたので、無事分かりやすい文字に変更できましたね!
モデルを作成する時は「def __str__(self):」を設定しておきましょう。
「control + D」でシェルを終了します。
管理者用のページを使う
shellで登録したり変更したりするのは面倒なので、管理者用のページを使いましょう!
管理ページはDjangoが用意してくれています!
まだ管理者が居ないので、以下のコマンドを使って管理者を作ります。(パスワード以外はコピペでOK)
$ python manage.py createsuperuser
# 名前は何でも良いのですが、ここでは「admin」を名前にします。
ユーザー名: admin
# メアドをadmin@example.comにしておきます。
メールアドレス: admin@example.com
# 自由にパスワードを設定してください(忘れないでね)
# 入力した文字は表示されませんが、ちゃんと入力できています。
Password: ********
Password (again): ********
Superuser created successfully.
これで管理者を作成できたので、管理ページにログインできるようになりました。
ローカルサーバーを起動しましょう。
$ python manage.py runserver
「http://127.0.0.1:8000/admin/」にアクセスしてみて下さい。このadminは、前回やったのプロジェクトのurls.pyで設定されていたURLですね!
ログイン画面になるので、先程設定したユーザー名とパスワードを入力してログインしてください。
するとこんな画面が出てくると思います。

しかし、ここには先程作成したpollsモデルが表示されていません。
実は、管理ページにモデルの内容を表示させるには、admin.pyで設定する必要があります。
pollsのadmin.pyを開いて次の内容を追加し保存しましょう。
from django.contrib import admin
from .models import Question, Choice
# adminにQuestionモデルを登録
admin.site.register(Question)
admin.site.register(Choice)
これでQuestionモデルとChoiceモデルが管理ページで表示されるようになったので、http://127.0.0.1:8000/admin/のページを更新してみましょう。

POLLSのQuestionとChoiceが表示されました!
Qestionsをクリックすると、先程shellで作成した「What’s up!」が表示されているはずです。
Choiceにはまだ何も無いので、右上の「CHOICEを追加」ボタンから、「Not much」と「Good」を追加しておきましょう。

コマンドまとめ
# pollsのmodels.pyからマイグレーションファイルを作成
$ python manage.py makemigrations polls
# マイグレーションファイルを元にデータベースにマイグレート(移行)する
$ python manage.py migrate
# shellを起動
$ python manage.py shell
終了は「control + D」
# 管理者を作成する
$ python manage.py createsuperuser
まとめ
- 色んな情報を保存するデータベースってのがある
- プロジェクトを新しく作ったら日本用の設定に変える
- 表のことをテーブルという
- models.pyからマイグレーションファイルが作成される
- マイグレーションファイルからテーブルが作成される
- マイグレーションファイルの中身は変更しない
- shellはコードの結果をリアルタイムで出力する
- 管理ページの内容はadmin.pyで変更する