Djangoで開発を行う際にやっておいて良かったこと
はじめに
案件内でDjangoでの開発環境の構築を行った際にやっておいて良かったことを紹介しようと思います。
開発環境は下記を利用しています。
※開発当時のバージョンです
settings.pyの分割
ローカル環境と本番環境で異なる設定が必要であり、環境変数だけではカバーしきれないものがあったため、設定ファイルを環境ごとに分割しました。
一例として、本番環境の設定ファイルではDjango REST frameworkのブラウザのGUIコンソールを非表示にする設定を記述しています。
if文を使って異なる設定を行うことも可能ですが、if文が増えてくると可読性が落ちたりメンテナンスがしずらいと思ったため、今回は設定ファイル分割の方法を選択しています。
やり方
- settings.pyがある場所にsettings ディレクトリを用意する
- settingsディレクトリに各環境の設定ファイルを用意する
- ローカル環境、検証環境、本番環境が存在している場合は以下のような形になる
- ディレクトリをPythonパッケージとして扱うために、__init__.pyファイルも用意する
- 環境変数で、
DJANGO_SETTINGS_MODULE="myproject.settings.local”
と設定することで、local.pyが読み込まれるようになる
全環境共通の設定ファイルも作成可能です。今回はbase.pyと名付けています。
各環境の設定ファイル内で以下の記述を行うことで、共通設定を読み込めます。
models.pyの分割
多くのテーブルを扱うとmodels.pyが肥大化しがちです。
今回は80個ほどのテーブルがあったため、可読性向上を目的にテーブルごとにファイルを作成しました。
やり方
- models.pyは削除し、models.pyがあった場所にmodels ディレクトリを用意する
- modelsディレクトリに各テーブルのファイルを用意する
- 各テーブルのファイルの中身はmodels.pyと同じ書き方で問題ない
- modelsディレクトリに__init__.py ファイルを用意する
- __init__.py ファイルで各テーブルのファイルをimportする
- 通常通り
python manage.py makemigrations
やpython manage.py migrate
を実行
fixtureの利用
マスターデータなどの投入をする際、fixtureを利用すると簡単に行えます。
今回は、チーム開発かつマスターデータが複数テーブルに存在していたため、fixtureを利用しました。
新しく入ってきたメンバーのローカル環境構築時に、自分のローカル環境のダンプデータを渡す手間が省けるので便利でした。
ただし、カラム等の設定が更新された際は、fixtureも更新する必要がある点には注意してください。
やり方
- fixturesディレクトリを作成する
- modelsやviewsと同じ階層に作成
- fixturesディレクトリにjsonファイルを作成する
-
python manage.py loaddata {ファイル名}.json
コマンドを実行することで、DBにデータ投入される
python manage.py dumpdata {ファイル名}.json
を実行すると、同じ形式でデータが出力されます。
今回はJSON形式を紹介しましたが、YAMLやXML形式のサポートもあります。
他の形式での書き方については、公式ドキュメントを参照ください。
https://docs.djangoproject.com/en/3.2/howto/initial-data/
SQLのログを表示する
N+1問題が発生していないか簡単に確認できるよう、発行されたSQLをログに出力するよう設定を行いました。
様々なデバッグ情報を表示してくれるDjango Debug Toolbar を使いN+1問題が発生していないか確認する方法もあります。必要に応じてこちらを採用するのも良いかと思います。
私は開発中にログを流しておくタイプなので、ログに出しておくだけでも結構N+1に気づくことができました。
やり方
- settings.pyに以下を記述
ログレベルや出力フォーマットのカスタムなども可能です。詳しい方法は公式ドキュメントを参照ください。
https://docs.djangoproject.com/en/3.2/topics/logging/
factory_boyの導入
テストコードを書く際に、factory_boyを利用しました。
factory_boyを利用することより、テスト用データの作成が容易になります。
後述しますが、自動でリレーション先のデータをよしなに作成してくれる機能があるため、整合性の取れたテストデータを用意するのが楽になった印象です。
テストフレームワークはPytestを使用しています。
やり方
- factory_boyをインストールする
- testsディレクトリの下にfactoriesディレクトリを用意する
- factoriesディレクトリに各テーブルのファイルを用意する
factoryの書き方も少し載せておきます。
リレーションがある場合にこのような書き方すると、自動でリレーション先のデータも作成してくれる
データを複数作成した時に、nに通し番号を入れてくれる
配列の中身の中からランダムで1つ選んで設定してくれる
呼び出し方は以下
公式ドキュメントでもサンプルが紹介されています。
https://factoryboy.readthedocs.io/en/stable/examples.html
リンター・フォーマッター導入
コードの一貫性を保つために、リンター・フォーマッターを導入しました。
今回はPEP8に準拠したかったため、flake8とblackを採用しています。
また、GitLabのCI/CDでflake8とblackのコマンドを実行し、チェックを自動的に行うようにしています。
やり方
- インストールする
- .flake8の更新
- Flake8では1行の最大文字数を79文字に規定している一方で、Blackでは88文字まで許容しているため、この競合を回避するためmax-line-lengthを88に設定
- flake8ではコロンの前に空白がある場合に警告を出す(E203)が、black は算術演算子の周りの空白を許可するため、この競合を回避するためE203を無視
- pyproject.tomlの更新
- コマンドの実行
-
flake8 --show-source {対象ディレクトリ}
- 例)flake8 --show-source app
-
black {対象ディレクトリ}
- 例)black app
-
さいごに
Djangoで開発を行う際にやっておいて良かったことを紹介してきました。
どれも簡単に行えるものなので、初期段階でささっと行っておくのが良さそうだと個人的に思いました。
Djangoでの開発の助けになれば幸いです。