Djangoプロジェクト構造のカスタマイズ（分割と構造化）


# 環境
Django 1.10

# プロジェクト構造カスタマイズ概要
デフォルトのプロジェクト構造は以下のようになっている．
> https://docs.djangoproject.com/en/1.10/intro/tutorial01/

```python
mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    app1/
    app2/
    app3/
# appはpython manage.py startapp appでつくる
```

これを以下のようにする．

```python
mysite/
    manage.py
    config/ # ここ
        __init__.py
        settings/ # ここ
            __init__.py
            base.py
            procution.py
            devlop.py
        urls.py
        wsgi.py
    apps/ # ここ
        app1/
        app2/
        app3/
```

# なぜカスタマイズか
appが増えてきたりするとappをひとつのディレクトリにまとめたいし，
settings.pyも，データベース情報などをローカル・ステージング・本番などで分割して管理したい．
またプロジェクトでの共通の静的ファイル（cssなど)もまとめてどこかへ置きたい．

> Djangoの設定ファイルであるsettingsの分割、構造化について。
> 開発、ステージング、本番、テストなど環境ごとにsettingsの内容は変える必要があるので、settings.pyを分割したり、共通部分をまとめたりする。

> http://tokibito.hatenablog.com/entry/20131015/1381763671



# コンフィグ系
## ディレクトリのリネーム
目標は以下のようにすることである．

```python
mysite/
    manage.py
    config/ # ココ！
        __init__.py
        settings.py
        urls.py
        wsgi.py
    app1/
    app2/
    app3/
```

まずコンフィグ系のフォルダをリネームする．
デフォルトではmysite/[config files]となっているが，
今回はconfig/[config files]のように他の名前に変えたい．

```python:settings.py
ROOT_URLCONF = 'config.urls'
WSGI_APPLICATION = 'config.wsgi.application'
```

またmanage.pyもいじる

```python:manage.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
```

## settingsの分割（前半）
参考：http://www.flounderedge.com/entry/2016/04/15/001316
目標は以下のようにすることである．

```python
mysite/
    manage.py
    config/
        __init__.py
        settings/ # ココ！
            __init__.py
            base.py
            production.py
            develop.py
        urls.py
        wsgi.py
    app1/
    app2/
    app3/
# appはpython manage.py startapp appでつくる
```

設定ファイル用のディレクトリを作っていく。 Pythonにこれはパッケージですよと伝えるために、 __init__.py を忘れない．

```bash
mkdir config/settings
touch config/settings/__init__.py
```

これで準備出来たので、設定ファイルを作っていく．
まず既存のsettings.pyをconfig/base.pyへ移動する．
次に，base.pyを環境ごとに拡張していくdevelop.pyとproduction.pyをつくる．

```bash
mv config/settings.py config/settings/base.py
touch config/settings/{develop,production}.py
```

ファイルを作成したら、新しいファイルたち（develop, production.py）の先頭で、base.py にある設定をすべて読み込む。

```python:production.py
from .base import *
```

このあとはdevelopやproductionで固有の設定をそれぞれのファイルでしていけばよい．

## settingsの分割（後半）
これまでで分割は終わったが，このままではDjangoは動かない．
まずmanage.pyの中の環境変数を弄る必要がある．
以下ではデフォルトでsettings/develop.pyを読み込むようにしている．

```python:manage.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.develop")
```

では本番で動かすとき（settingsを切り替えたいとき）はどのようにすればよいか？以下のようにする．

```
python manage.py shell --settings=config.settings.production
```

# アプリケーションをまとめる
目標は以下のようにすることである．

```python
mysite/
    manage.py
    config/
        __init__.py
        settings/
            __init__.py
            base.py
            production.py
            develop.py
        urls.py
        wsgi.py
    apps/ # ここ！
        app1/
        app2/
        app3/
```

base.pyに以下を加える．

```python:settings/base.py
# Add apps/ to the Python path
sys.path.append(os.path.join(PROJECT_ROOT, "apps"))
```

# 共通の静的ファイル置き場をつくる

Djangoの公式にあった気がする．

# 参考
+ [偏った言語信者の垂れ流し](http://tokibito.hatenablog.com/entry/20131015/1381763671)
+ [えんがわ](http://www.flounderedge.com/entry/2016/04/15/001316)
+ [包丁一本さらしに巻いて](http://akirachiku.com/2014/04/01/road-to-django-best-practice.html)