【Django】設定ファイル(settings.py)を開発環境用と本番環境用に分割したい

#### 背景
Python/Djangoを用いて個人のWEBサービスを制作し本番運用する際に失敗したことから、設定ファイル(settings.py)を分割して管理する方法について検討し、整理しました。
以下に記します。

先人たちの知恵をお借りするなどして解決できたことを、この場をお借りして感謝するとともに、大変恐縮ですが自分のメモとしても、こちらへまとめておきます。

<font color="#ff0000">※ 3.-5) from行の指定内容を修正いたしました。大変失礼いたしました。(2020/12/04 修正)</font>

#### 環境
##### （本番環境）
- AWS EC2 (Amazon Linux 2)
- Python 3.7.9　　　　※2020/11/29時点のAmazon Linux2でのデフォルト
- Django 3.1.3
- PostgreSQL 11.5　　※同上
- Nginx 1.12　　　　　※同上
- Gunicorn

##### （開発環境）
- Windows 10 Pro
- Python 3.9
- Django 3.1.3
- PostgreSQL 13.1
- Nginx 1.19.5
- Gunicorn


### 1.現象 
本番環境にて、設定内容の一部分を開発環境のままで使ってしまい、ログが大量に書かれてしまった。


### 2.原因
`settings.py`ファイルは、開発環境と本番環境とで内容を書き換えないといけなかった。
横着して、ファイルを分けずに編集しながら、開発と本番とを行き来していました。


### 3.対処
`settings.py`ファイルを開発環境用と本番環境用に分けて管理する。

#### 3-1. ファイルを分けた上で`__init__`ファイルを用いて管理する 

設定ファイル群を格納するための「settings」ディレクトリを、プロジェクトディレクトリに作成します。

1) 元の構成

```:python
venv/                               仮想環境のプライマリーディレクトリ
    project/                        プロジェクトディレクトリ
        __init__.py
        settings.py                 設定ファイル
        urls.py
        wsgi.py
```

2) settingsディレクトリを作成して、`settings.py`を移動

```:python
venv/                               仮想環境のプライマリーディレクトリ
    project/                        プロジェクトディレクトリ
        settings/                   設定ファイル用のディレクトリ  <--追加
            settings.py             <-- 移動
        __init__.py
        urls.py
        wsgi.py
```

3) `settings.py`をコピーして、`settings_common.py` `settings_develop.py` を作成した上、それぞれ後述の通りに修正
ファイル名は一例です。

```:python
venv/                               仮想環境のプライマリーディレクトリ
    project/                        プロジェクトディレクトリ
        settings/                   設定ファイル用のディレクトリ
            settings.py             
            settings_common.py      <-- 追加
            settings_develop.py     <-- 追加
        __init__.py
        urls.py
        wsgi.py
```

|用途|ファイル名|内容|
|:--|:--|:--|
|本番環境用　|`settings.py`|本番環境独自の設定を記述。共通部分について必要な設定は`settings_common.py`からimportする。|
|共通|`settings_common.py`|本番・開発の各環境に共通の設定を記述。|
|開発環境用　|`settings_develop.py`|開発環境独自の設定を記述。共通部分については上述の通り。|

【注意事項】
SECRET_KEY は名前の通り**「秘密」**です。`os.environ.get('SECRET_KEY')` として、環境変数として設定しましょう。
その他、データベースのユーザー名やパスワードなども同様です。


4) 空の`__init__`ファイルをsettingsディレクトリに作成

```:python
venv/                               仮想環境のプライマリーディレクトリ
    project/                        プロジェクトディレクトリ
        settings/                   設定ファイル用のディレクトリ
            __init__.py             <-- 追加
            settings.py
            settings_common.py
            settings_develop.py
        __init__.py
        urls.py
        wsgi.py
```

5) settingsディレクトリ内の`__init__.py`ファイルへ、以下の内容を追記する。

```python:__init__.py
# settings/__init__.py

from .settings import *                  # settings.py(本番環境用)をimport

try:
    from .settings_develop import *      # settings_develop.py(開発環境用)をimport
except:
    pass
```

`__init__.py`ファイルとは；

> ディレクトリをPythonパッケージとして扱うために、`__init__.py`ファイルを含める必要があります。
通常は中身が空のファイルですが、初期化コードを記述することもできます。

上記の内容とすることで、本番環境では`settings.py`モジュールのみが、開発環境では`settings_develop.py`モジュールが呼び出されます。
（`settings_common.py`の内容はそれぞれにimportされていますので、`__init__`ファイルへの記述は不要です。）


### 4.結果
`settings.py`ファイルの内容を、開発環境と本番環境とで確実に分けて管理することができました。
また、`__init__.py`ファイルへ設定することで、起動時にどちらを読み込むのかを都度気にせずに済むようになりました。
　
　
以上、設定ファイルの分割と管理についてでした。

---
#### 参考
- [Python の `__init__.py` とは何なのか](https://qiita.com/msi/items/d91ea3900373ff8b09d7)　[@msi](https://qiita.com/msi)様

---
#### (編集後記)
ひとつの`settings.py`を編集しながら使い回してはいけない、という教訓になりました。
みなさまには「べからず集」（反面教師）として、お伝えできればと思い、まとめてみました。
もっとこんな良い方法があるよ！、これがベストプラクティスです！という情報がありましたら、是非、ご教示いただけましたら幸いです。