openshiftに対応するためのDjango2コーディング時に気を付けるべき点

# いままでのおさらい

前回まででnginx+gunicorn+Django2をminishiftで動作させることには成功しました。
ここでOpenShift上で特に気を付けるべきDjango2プロジェクトの書き方に触れておきたいと思います。

それはずばり「OpenShift側で設定した環境変数を`settings.py`に取り込む！」です。

これをしておくとイチイチ、ソースを修正することなく環境変数の設定変更＆リビルドで行けちゃいます。


- [Win10環境でDjango2のREST APIを試してみる](https://qiita.com/imp555sti/items/cbe579fbbfa3837075f3)
- [minishift V1.28.0でDjango2を動かす①：テンプレート確認](https://qiita.com/imp555sti/items/7fcb6d507c4e0eae5b3a)
- [minishift V1.28.0でDjango2を動かす②：テンプレート＆s2iソースの作成](https://qiita.com/imp555sti/items/728e774cd54e5781884b)
- [minishift V1.28.0でDjango2を動かす③：s2iソースの修正＆ビルド](https://qiita.com/imp555sti/items/f6ea232c1935f7c9042c)
- [minishift V1.28.0でDjango2を動かす④：残課題](https://qiita.com/imp555sti/items/ac7839d2a846f69a2bc1)
- [minishift V1.28.0でnginx+gunicorn+Django2を動かす](https://qiita.com/imp555sti/items/7733b48f41fc37ddda24)
- [minishift V1.28.0でnginx+gunicorn+Django2を動かす。あっcreatesuperuser忘れてた(笑)](https://qiita.com/imp555sti/items/e4ce4524fe8535313616)
- [openshiftに対応するためのDjango2コーディング時に気を付けるべき点](https://qiita.com/imp555sti/items/e9b37f0d5430220da690)

# 環境変数の参照方法
Django2でのOS環境変数の取得方法は`os.getenv`ですね。

```python
import os
os.getenv('<環境変数名>','<デフォルト値>')
```

# 実際に`settings.py`に使ってみる

実際に利用するシーンとしては`SECRET_KEY`、`DEBUG`、`ALLOWED_HOSTS`、`DATABASES`、`LANGUAGE_CODE`、`TIME_ZONE`、あとはメール送信の設定などでしょうか


## `SECRET_KEY`を環境変数から設定する
元コード

```python:settings.py
SECRET_KEY = 'g*jrfy&_%p3y0-_bgilt)e(dsy9^hag2(kc3%b1u9hn****kh3'
```

環境変数対応版

```python:settings.py
SECRET_KEY = os.getenv(
    'DJANGO_SECRET_KEY',
    # safe value used for development when DJANGO_SECRET_KEY might not be set
    'g*jrfy&_%p3y0-_bgilt)e(dsy9^hag2(kc3%b1u9hn****kh3'
)
```

## `ALLOWED_HOSTS`を環境変数から設定する
ある時期は限定したIPからのアクセスに絞って、OKなら全体に公開する的な使い方もできますね。

元コード

```python:settings.py
ALLOWED_HOSTS = ['*']
```

環境変数対応版

```python:settings.py
ALLOWED_HOSTS = [os.getenv('DJANGO_ALLOWED_HOSTS','*')]
```

## `DATABASES`を環境変数から設定する
同様にDBの設定についても可変にできるといいですね。ちょっとだけ複雑になりますが

元コード

```python:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'database_name',
        'USER': 'user_name',
        'PASSWORD': 'password',
        'HOST': 'xxx.xxx.xxx.xxx',
        'PORT': '5432',
    }
}
```

環境変数対応版

```python:settings.py
engines = {
    'sqlite': 'django.db.backends.sqlite3',
    'sqlite3': 'django.db.backends.sqlite3',
    'postgresql': 'django.db.backends.postgresql',
    'mysql': 'django.db.backends.mysql',
    'oracle': 'django.db.backends.oracle',
}

engine = engines.get(os.getenv('DATABASE_ENGINE'), engines['sqlite'])

if engine == engines['sqlite']:
    DATABASES = {
        'default': {
            'ENGINE': engine,
            'NAME': os.path.join(BASE_DIR, os.getenv('DATABASE_NAME','db.sqlite3')),
        }
    }
else:
    service_name = os.getenv('DATABASE_SERVICE_NAME', '').upper().replace('-', '_')

    DATABASES = {
        'default': {
            'ENGINE': engine,
            'NAME': os.getenv('DATABASE_NAME'),
            'USER': os.getenv('DATABASE_USER'),
            'PASSWORD': os.getenv('DATABASE_PASSWORD'),
            'HOST': os.getenv('{}_SERVICE_HOST'.format(service_name)),
            'PORT': os.getenv('{}_SERVICE_PORT'.format(service_name)),
        }
    }
```

もちろん参照する環境変数は`DeployConfig`の中に`env`に定義しておいてください。
その際に気を付けるべき点としては、変数名がすべて大文字になり、`-`があると`_`に置き換わることです。
なのでこのコードなんですよね。

```python
service_name = os.getenv('DATABASE_SERVICE_NAME', '').upper().replace('-', '_')
```

一部はDeploy時にOpenShistが自動で値を定義するものもあります。
例えばDB設定の例の`<NAME>_SERVICE_HOST`、`<NAME>_SERVICE_PORT`などはそれに当たります。

何が環境変数にセットされているか確認するには、s2iスクリプトの`run`に`set`コマンドでも入れてデバックすると良いでしょう。