Djangoプロジェクトの構成
プロジェクトとアプリケーション
DjangoでのWebアプリケーション開発では、プロジェクトとアプリケーションという要素を作成して進めていきます。プロジェクトとは、Webアプリケーション全体のことを指します。アプリケーションとは、プロジェクトの中の1つの側面を実装するための小さなライブラリのことです。ひとつのプロジェクトは複数のアリケーションから成り立っています。
たとえばファッションのECサイトを構築する場合は、ユーザー管理機能とECショップ機能、配送管理機能などを別々のアプリケーションとして開発していきます。
先ほど言及したDjangoの設計思想の1つに、疎結合(Loose coupling)があります。アプリケーションにおいても、ほかのアプリケーションへの依存は極力減らして、自分がすべき仕事にのみ集中するような設計が望ましいとされています。
標準のプロジェクト構成
それではプロジェクトを作成しましょう。Djangoをインストールすると、django-admin
コマンドが使えるようになっています。django-admin startproject <プロジェクト名>
を実行することで、Djangoプロジェクトが作成されます。
(env) $ django-admin startproject mysite
mysite *1 ├── manage.py └── mysite *2 ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
mysiteプロジェクトを格納するためのmysiteディレクトリ(*1)ができて、その配下にmysiteパッケージ(*2)とmanage.pyが作成されています。この内側のmysiteはプロジェクトの設定ファイルを含んだPythonパッケージです。manage.pyはdjango-adminに対する薄いラッパで、このプロジェクト専用のコマンドラインユーティリティとなります。
ではさっそくmanage.pyを使ってアプリケーションを作成します。python manage.py startapp <アプリケーション名>
を実行します。
(env) $ cd mysite (env) $ python manage.py startapp my_app
mysite ├── my_app │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── mysite ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
このようにアプリケーションを作成して開発していきます。これがDjango標準のファイル構成となります。ただこの構成でアプリケーションを増やしていくと、ルートディレクトリにたくさんのPythonパッケージができていって複雑になりがちです。さらにこのルートディレクトリには、READMEやGit関連ファイルなどDjangoに関係ないファイルも置かれます。ですので、ルートディレクトリはなるべく簡潔に保っておきたいところです。
実践的なプロジェクト構成
この問題を解決するために、Two Scoops of Djangoという書籍では以下の構成を推奨しています。
<repository_root>/ ├── <configuration_root>/ ├── <django_project_root>/ ├── .gitignore ├── README.rst
構成要素 | 役割 |
---|---|
repository_root | Gitリポジトリのルート |
configuration_root | プロジェクトの設定ファイルパッケージ |
django_project_root | Djangoアプリケーション群のルート |
この構成では、<django_project_root>
配下にDjangoアプリケーションを作っていくことになります。<configuration_root>
には、settings.pyやurls.pyなどプロジェクトの設定ファイルが含まれます。以下のコマンドを打てば、この構成を手にできます。
(env) $ mkdir mysite2 (env) $ cd mysite2 (env) $ django-admin startproject config . (env) $ mkdir mysite2 (env) $ cd mysite2 (env) $ django-admin startapp my_app
mysite2 ├── config │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── mysite2 └── my_app ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py
ディレクトリ | 構成要素 | 役割 |
---|---|---|
mysite2/ | repository_root | Gitリポジトリのルート |
mysite2/config/ | configuration_root | プロジェクトの設定ファイルパッケージ |
mysite2/mysite2/ | django_project_root | Djangoアプリケーション群のルート |
本連載ではこの構成でDjangoプロジェクトを開発していくことにします。ただプロジェクト構成に正解というものはないので、それぞれの規模や状況に合わせて柔軟に変えてもらってかまいません(実際、筆者が現在の業務で扱っているDjangoプロジェクトは<configuration_root>
が<django_project_root>
に内包されています)。
Cookiecutter Django
Cookiecutterとはプロジェクトのひな型を作成するためのCLIツールです。そしてCookiecutter Djangoは、Two Scoops of Djangoの著者が開発したDjangoプロジェクト用のCookiecutterです。Cookiecutter Djangoを使うことで、手軽に先ほど紹介した構成のDjangoプロジェクトをセットアップできます。では実際に試してみましょう。
(env) $ pip install "cookiecutter>=1.4.0" (env) $ cookiecutter https://github.com/pydanny/cookiecutter-django
するとプロジェクトの設定についていろいろ聞かれるので、ひとつずつ答えていってください。
project_name [Project Name]: mysite3 project_slug [mysite3]: author_name [Daniel Roy Greenfeld]: massa142 email [you@example.com]: massa142@example.com description [A short description of the project.]: This is a sample django application. domain_name [example.com]: mysite.com version [0.1.0]: 0.0.1 timezone [UTC]: Asia/Tokyo use_whitenoise [y]: n use_celery [n]: n use_mailhog [n]: n use_sentry_for_error_reporting [y]: n use_opbeat [n]: n use_pycharm [n]: n windows [n]: n use_docker [n]: n use_heroku [n]: n use_elasticbeanstalk_experimental [n]: n use_compressor [n]: n Select postgresql_version: 1 - 9.6 2 - 9.5 3 - 9.4 4 - 9.3 5 - 9.2 Choose from 1, 2, 3, 4, 5 [1]: 1 Select js_task_runner: 1 - Gulp 2 - Grunt 3 - None Choose from 1, 2, 3 [1]: 3 custom_bootstrap_compilation [n]: n Select open_source_license: 1 - MIT 2 - BSD 3 - GPLv3 4 - Apache Software License 2.0 5 - Not open source Choose from 1, 2, 3, 4, 5 [1]: 1
この質問に答えるだけで、プロジェクトの初期構築が完了しました。質問の答えに応じて、ライブラリやインフラに特化した設定ファイルも生成してくれます。ただCookiecutter Djangoは対応しているデータベースがPostgreSQLのみであるなど、このまま使える機会は限られてきます。
しかしディレクトリ構成においては参考にできる点が多くあります。特にsettingsとrequirementsの書き方は広く知られているやり方ですので確認しておきましょう。
settingsファイルの分割
ローカル環境での開発ができるだけで十分なのであれば、単純なsettings.py
ファイル1つで問題ありません。しかし実際の運用となると、本番環境やテスト環境など複数の環境でアプリケーションを動かす必要がでてきます。この対応策の1つとして、各用途に応じてsettingsファイルを分割するという方法があります。
settings ├── __init__.py ├── base.py ├── local.py ├── production.py └── test.py
ファイル | 役割 |
---|---|
base.py | すべてに共通の設定 |
local.py | ローカル開発用の設定 |
production.py | 本番環境用の設定 |
test.py | テスト実行時用の設定 |
base.py以外のsettingsファイルには、from .base import *
が記述されています。base.py
の設定はすべてインポートされたうえで、各用途に合わせた設定が追加・上書きされます。
from .base import * # noqa # DEBUG # ------------------------------------------------------------------------------ # Turn debug off so tests run faster DEBUG = False TEMPLATES[0]['OPTIONS']['debug'] = False
複数の環境に対応するsettingsの書き方には、1つのファイルで管理するやり方もあります。環境変数とif文を用いることによって、settings.pyひとつで複数の環境に対応できます。
このsettingsの管理方法にも正解はありません。プロジェクトの規模に応じて、適切なアプローチをとってください。今回の連載では、ファイルを分割するやり方を採用しています。
requirementsファイルの分割
settingsファイルと同様にrequirementsファイルも用途に応じて分割することがよく行われています。
requirements ├── base.txt ├── local.txt ├── production.txt └── test.txt
base.txt以外のrequirementsファイルには、-r base.txt
が記述されています。このためpip install -r requirements/local.txt
を実行した際に、base.txt
とlocal.txt
に記載されているパッケージをインストールできます。
# Local development dependencies go here -r base.txt coverage==4.4.1 django-coverage-plugin==1.5.0 Sphinx==1.6.4 django-extensions==1.9.6 Werkzeug==0.12.2 django-test-plus==1.0.18 factory-boy==2.9.2 django-debug-toolbar==1.8 # improved REPL ipdb==0.10.3 pytest-django==3.1.2 pytest-sugar==0.9.0
この階層化は賢いやり方ですが、注意しておくべき点は複雑にしすぎないということです。ステージングやCIなどといった環境にも合わせて分割しすぎると、環境間の差分が把握しづらくなったり、依存関係が複雑になって保守が難しくなったりします。
またCookiecutter Djangoは本番用にproduction.txtを用意していますが、本番だけ異なる依存があるという管理方法はあまりお勧めできません。本番環境でのみ発生する不具合につながりかねないからです。requirementsファイルの分割は、ローカル開発用・テスト用くらいのシンプルな粒度にとどめておくのがよいでしょう。