Python Django チュートリアル(1)

  • 107
    いいね
  • 0
    コメント

勉強会用資料です.
django1.8のチュートリアルを辿りつつ説明していきます.
https://docs.djangoproject.com/en/1.8/intro/tutorial01/

日本語の公式ドキュメントはバージョン1.4が最新なので若干違いが有りますが大まかな流れは一緒なので一読するのもいいと思います.
http://django-docs-ja.readthedocs.org/en/latest/intro/tutorial01.html

公式サイトの説明ではプロジェクト名がmysiteになっていますが,
tutorialプロジェクトとして作成していきます.

追記(2015/11/18):チュートリアルのチュートリアルを作成しました.
チュートリアルまとめ

環境

OS:Mac OSX10.11
python:3.4.2
django:1.8.5

ソースコード

githubにチュートリアルのソースコードを置いておきます.
要所要所にtagを付け,できるだけ細かくコミットしていきますので参考にしてください.
https://github.com/usa-mimi/tutorial

ファイル構成

こんなファイル構成で進めていきます.

tutorial/  # gitでcloneした際にできるディレクトリ
    ├ .git/
    ├ .gitignore
    ├ ...
    └ tutorial/  # 説明は特に注釈がない限りここをrootとして説明します
          ├ manage.py  # djangoのコマンドを実行する時に指定する
          ├ ...
          └ tutorial/
                ├ ...
                ├ urls.py  # projectのURL
                └ settings.py  # projectの設定ファイル

トップのtutorialディレクトリをgitの対象にしてます.
git用のREADMEやdeploy用の設定などdjango本体に関係ないファイルを置くためにこうしてます.

このディレクトリ内で
(tutorial) $ django-admin startproject tutorial
このコマンドを実行すると
tutorial/tutorial以下のファイル,ディレクトリが自動で生成されます.

gitでproject_startタグをつけているのが上記コマンドを実行した直後の状態です.

ここからは特に注釈のない場合tutorial/tutorialを基準として説明していきます.

自動作成されるファイルの説明

https://docs.djangoproject.com/en/1.8/intro/tutorial01/#creating-a-project

./manage.py

コマンドラインで色々な操作をする時に指定するファイルです.
サーバの起動やDBのmigrate,自作コマンドの実行などを行う場合はこのファイルにコマンドを渡して実行させます.

$ python manage.py runserver
$ python manage.py migrate
こんな感じです.

manage.pyは実行権限がついているので
$ python manage.py のかわりに $ ./manage.py と書くこともできます.

引数を何も渡さない場合は実行できるコマンド一覧が表示されます.
もっと詳しく知りたい方は公式サイトを参考にしてください.
https://docs.djangoproject.com/en/1.8/ref/django-admin/

実行して以下のような出力された方はdjangoがinstallされてません.
仮想環境を作成しdjangoをinstallするか,workon コマンドで仮想環境に入ってください.

$ ./manage.py
Traceback (most recent call last):
  File "./manage.py", line 8, in <module>
    from django.core.management import execute_from_command_line
ImportError: No module named django.core.management

tutorial/settings.py

プロジェクトの設定ファイルです.
有効にするアプリやミドルウェア,
DB接続設定や各種ディレクトリなど諸々を設定します.

設定項目を詳しく知りたい方は公式サイトを参考にしてください.
https://docs.djangoproject.com/en/1.8/topics/settings/

tutorial/urls.py

サーバのURL設定です.requestされたURLを見てどのview(後述)でresponseを返すかはこのファイルに書きます.
settings.pyの中でROOT_URLCONFとして指定されてます.

公式説明→https://docs.djangoproject.com/en/1.8/topics/http/urls/

データベースの作成

ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial01/#database-setup
ソース→project_startタグ

データベースの設定

チュートリアルに習って次はデータベースの作成をしてみましょう.
どのDBを使うかは設定ファイル(tutorial/settings.py)に記述されています.
設定ファイルを開いて77行目付近を見てみてください.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

デフォルトでは上記の用にsqlite3を使うようになっており,manage.pyと同じディレクトリに
db.sqlite3という名前のDBファイルを使うことになっています.
sqliteエンジンの場合はNAMEがsqliteファイルへのpathになります.
BASE_DIRはmanage.pyが置いてあるディレクトリを指してます.
os.path.join はシステムに応じたセパレータでパスを連結してくれる関数です.

mysqlサーバやpostgresqlサーバを使いたい人はこのファイルを以下のように書き換えてください.

# mysqlサーバ
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}
# postgresqlサーバ
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

補足:sqlite

sqliteはデータベースをファイルで管理する簡易的なデータベースです.
サーバを用意する必要がなく,データベースの削除もファイルを消すだけで簡単にできるのでプロトタイプ作成には非常に向いています.
しかし通常のDBサーバに比べてアクセスが遅く,同時アクセス時にトラブルになりがちなので
完成したプログラムを動かす際はmysqlpostgresqlを使うようにしましょう.
macの場合は標準でインストールされていますが,windowsの場合は手動でインストールする必要があるようです.

インストールの参考サイトのURLを貼っておきますので参考にしてください.
http://www.dbonline.jp/sqliteinstall/install/index1.html

データベース作成

データベースの設定を終えたら実際にデータベースを作成(テーブル追加)しましょう.
データベース作成のコマンドはmigrateです.
$ ./manage.py migrate

mysqlやpostgresqlを使う場合は予め空のデータベースを用意して上げる必要があるかもしれません.
sqlite3を使う場合は何も考えず.コマンドを実行するとファイルが作成されます.

特に設定を弄らずにコマンドを実行すると認証に使用するユーザ情報やセッション情報を保存するためのテーブルが作成されます.

$ ./manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: messages, staticfiles
  Apply all migrations: contenttypes, auth, sessions, admin
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... 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 sessions.0001_initial... OK

補足:syncdb

django1.6まではsyncdbというコマンドを使ってデータベースの初期化を行っていました.
このコマンドを実行するとmigrateコマンドと,次に説明するcreatesuperuserコマンドを
続けて実行するような動きになります.
django1.8の時点でもコマンドは残っていて実行できますが,django1.7から公式では非推奨になっています.

日本語ドキュメントはdjango1.4のためsyncdbで説明されていると思いますのでご注意ください.

サーバ起動確認

ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial01/#the-development-server
ソース→project_startタグ

ブラウザで確認

djangoフレームワークにはサーバ機能もついており,開発時に専用のサーバを用意する必要がありません.
実行するコマンドはrunserverです.
実行するとデフォルトでは8000番ポートを使用して開発用サーバが起動します.
この状態でブラウザで http://localhost:8000/ にアクセスすることで動作確認ができます.

$ ./manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
October 31, 2015 - 08:55:38
Django version 1.8.5, using settings 'tutorial.settings'
Starting development server at http://127.0.0.1:8000/  # ← 起動時のアドレス
Quit the server with CONTROL-C.
[31/Oct/2015 09:06:54] "GET / HTTP/1.1" 200 1767  # ← ブラウザでアクセスした時に表示される

Kobito.uICdzG.png
何も作ってないからデフォルト画面が表示される.

ポート番号を変更したい場合は
$ ./manage.py runserver 8080 のようにポート番号を引数に与えます.
同じLAN内にあるPCからアクセスしたい場合は
$ ./manage.py runserver 0.0.0.0:8000 のように書いとくと
同じLAN内からアクセスできるようになります.
マシンのIPはipconfigifconfigなどのコマンドで調べてください.

補足:runserverの自動読み込み

runserverで起動中にプログラムを変更したらdjangoは自動的に再起動してくれます.
runserverしているターミナルを持ってきて一度停止して起動... なんてことはする必要ありません.
ただ,新しいテンプレートディレクトリを追加した場合など,自動で読み込まれないこともあるので少しだけ注意しましょう.

アプリ追加

ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial01/#creating-models
ソース→ start_projectタグ → add_app_4_database_migrationタグ

いよいよアプリケーションを追加していきます.
チュートリアルではpollsという投票アプリを例にとり,モデルの作成方法を説明しています.

その前にdjangoでアプリケーションを使いする流れについて説明しておきます.

  1. $ ./manage.py startapp appname でアプリケーションを追加する.

  2. appname/models.py にそのアプリで使用するモデル(データベースのテーブル)を記述する.

  3. project/settings.pyに作成したアプリを追加する

  4. データベース更新

  5. appname/views.py にモデルの表示や操作(追加,編集など)を記述する.
    使用するhtmlもここで用意.

  6. appname/urls.py を記述し,urlとviewsを紐付ける

  7. project/urls.pyからappname/urls.pyを読み込む.

1から4まではこのチュートリアルで行います.
5以降はチュートリアル3で説明します.
(チュートリアル2は「管理画面」の話です)
ソースのタグはadd_app_xの形式で付けています.

1. pollsアプリ追加

manage.pyのstartappコマンドを実行しましょう.
アプリ名のついたディレクトリといくつかのファイルが自動的に作成されます.

$ ./manage.py startapp polls
$ tree polls
polls
├── __init__.py
├── admin.py  # 管理サイト絡みのファイル
├── migrations  # 自動生成されるので特に触らない
│   └── __init__.py
├── models.py  # テーブル情報や動作を記述していくファイル
├── tests.py  # testを書きたい場合はこのファイルを編集する
└── views.py  # requestを受け取りresponseを返す関数を追加していく

チュートリアル3では,これに加えてforms.py, templates/, urls.pyを手動で追加します.

2. モデルの記述

チュートリアルにならってpolls/models.pyを書き換えましょう.
models.Modelクラスを継承して作ったクラスはDBのテーブルを表すクラスになります.
models.~Fieldインスタンスを使用して設定するプロパティはテーブルのカラムを表現します.
プロパティ名がそのままテーブルのカラム名になります.
チュートリアルではQuestionテーブルとChoiceテーブルを設定しています.

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)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

補足:Model

今回のチュートリアルでは出てきませんが,Metaクラスを設定することでクラスの振る舞いを色々と調整できます.
ドキュメント→https://docs.djangoproject.com/en/1.8/ref/models/options/

データ取得時のデフォルトの並び順を指定したり,作成されるテーブルの名前を変更することができます.

デフォルトではappname_modelnameのテーブルが作成されます.
チュートリアルの例ではpolls_question, polls_choiceのテーブルが作成されます.
特別な理由がない限りテーブル名の変更はオススメしません.

他の有用な設定項目としては次のチュートリアルで説明する管理ページでの名前の変更や,
複数fieldのunique制約の設定(例えば日付項目で制約を掛ける)などです.

記述方法は以下の様な感じです

class Question(models.Model):
    class Meta:
        app_label = 'polls'
        verbose_name = '質問'
        table_name = 'polls_question'

補足:Field

どんな種類のFieldがあるかは本家のドキュメントを参考にしてください.
ドキュメント→https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types

一般的なDBのカラム型に相当するものは網羅されているはずです.
fieldにはいくつかの共通のオプションの他に,フィールド独自のオプション,必須項目を持っています.
例えばCharFieldは一般的なDBのchar型を表現します.
char型は文字数の指定が必須であるため,djangoのCharFieldmax_length引数が必須となっています.

ForeignKeyは少し特殊なFieldで,他モデルへのリレーションを表現します.
カラム型はリレーションを貼ったモデルの主キーと同じ型になり,カラム名はプロパティ名に_idが追加されたものになります.
チュートリアルの例では,question_idという名前のinteger型のカラムが作成されます.
(デフォルトの主キーがinteger型のため)

同ファイル内で定義されているモデルへのリレーションのため,引数に直にクラスを渡していますが,
別ファイルで定義されているモデルへリレーションを貼りたい場合はapp.modelの形式で文字列でリレーションを張るモデルを指定します.
例:question = models.ForeignKey('polls.Question')

3. アプリケーションの追加

ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial01/#activating-models

startappでアプリを追加しただけではそのアプリケーションは有効化されません.
tutorial/settings.pyの中に使用するアプリ一覧の項目があるので,そこに作成したアプリを追加しましょう.
設定するための変数はsettings.pyの33行目付近にあるINSTALLED_APPSという名前のタプルです.

tutorial/settings.py
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',  # ← これを追加
)

今回は自作したpollsアプリを追加しましたが,pipなどで出来合いのdjangoアプリケーションを追加する場合も同様にINSTALLED_APPSにアプリ名を追加しましょう.
ここに追加するとmigrationやtemplates,testなどの読み込み対象になります.

4. データベース更新

ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial01/#activating-models
3. アプリケーションの追加と同じ)

settings.pyを変更したらmakemigrationsコマンドを実行しましょう.
このコマンドは各アプリのmodelの変更を検出し,自動でmigrationファイルを作成してくれます.
このコマンドを実行してmigrationファイルを作った後に,migrateコマンドを実行することで
DBへモデル(=テーブル)の変更を反映させます.

$ ./manage.py makemigrations
Migrations for 'polls':
  0001_initial.py:
    - Create model Choice
    - Create model Question
    - Add field question to choice

変更があったら自動的で検出してmigrationファイルが作成されます.
今回はテーブルの追加なのでありませんが,フィールドの追加時にdefault値を設定していない場合は
defalt値を何にするかを聞かれます

$ ./manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: messages, staticfiles
  Apply all migrations: admin, auth, polls, contenttypes, sessions
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying polls.0001_initial... OK

migrateコマンドを実行することでdatabaseに設定が反映されます.
どのmigrateコマンドを実行したかはdjango_migrationsテーブルに記録されています.

--
本家のチュートリアルではこの後でモデルのカスタマイズ,シェルでの実行を行っていますが,
本チュートリアルでは割愛します.
モデルのカスタマイズについては次のチュートリアルで説明します.
https://docs.djangoproject.com/en/1.8/intro/tutorial01/#playing-with-the-api

--
次のチュートリアルへ

チュートリアルまとめ