DjangoがHerokuで動かない
HerokuにDjangoをDEGUB=Falseでデプロイが成功しても、接続するとServer Error(500)が表示されて悲しい気持ちになってしまい、いやいやながら不安な心を抱いてDEBUG=Trueにしている人(初心者)のための情報です。
私のような英語がよく理解できず、かつ翻訳内容すら正しく読みとる読解力が足りない人間がDjango公式などの文書を読むと、とかく勘違いしたり理解しないままやっちまうのでServer Error(500)を出しがちです。
そんな私がなんとか動かすことに成功した環境設定について、その注意点まとめてみた。
Herokuへのデプロイはコマンドを叩くんじゃなくて、Githubからデプロイする機能を使ってで行ってます。こっちのほうがボタン一発だから超カンタン。なんならGithubのソースが更新されたら、自動的にデプロイしてくれる(やったことないけど)ので超ベンリ(のはず)
静的ファイルの配信のやり方(whitenoiseを使いかた)
まずは公式文書を読んでみよう。
Heroku公式(Djangoと静的アセット)
https://devcenter.heroku.com/ja/articles/django-assets
WhiteNoise公式 (Using WhiteNoise with Django)
https://whitenoise.evans.io/en/stable/django.html
setting.pyの設定
whitenoise公式に書いてあること
###'whitenoise.middleware.WhiteNoiseMiddleware'は必ず'django.middleware.security.SecurityMiddleware'の直下に書け
Heroku公式をみると単にMIDDLEWAREの最初に書け的な事が書いてあるけど、本家Whitenoise公式では
「SecurityMiddleware以外の他のどのミドルウエアよりも上に書け」とあります。
しかし試しに一番下に書いてもServer Error(500)にはなりませんでした。
とはいうもののHeroku公式にも「最上段にかけ」と書いていますし、どこでどんな影響が出かがわからないので、言われて通りに設定するのがいいと思います。
###こんなかんじですね
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', <= ここにSecurityMiddlewareがある
'whitenoise.middleware.WhiteNoiseMiddleware',
# ... <= その他もろもろの定義が続く
]
###ちなみにHeroku公式の説明では
MIDDLEWARE_CLASSES = (
# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/
'whitenoise.middleware.WhiteNoiseMiddleware',
...
とかいてあって、django.middleware.security.SecurityMiddlewareについては
これは、settings.py の (先頭にある) ミドルウェアのセクションで実行されます。
というようなよくわからん書き方がされているうえに、
MIDDLEWARE_CLASSES = (
という新しい定数をMIDDLEWAREとは別に追加する必要があるのかと思ってしまった。(結果的にそうじゃなかった)
staticファイル関連の設定
staticファイル関係の設定は以下の通り。(おそらくmediaも同じように定義するんじゃないかな(こちらは未確認))
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
####そんなHeroku公式には同じ場所に
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
を追加しろと記述があるけれど、こいつを設定するとデプロイ(具体的にはmanage.py collectstaticが)失敗します。
削除しててもデプロイ成功するし静的ファイル配信も問題なしだったから、STATICFILES_DIRSは追加しなくてもオーケー。(これについては他の方も書かれていたのでおそらく正しい)
ちなみにHerouはデプロイ時に manage.py collectstatic --noinputを自動的に実行してくれます。失敗するとデプロイにも失敗するのですぐに分かります。
追加 2021/09/01)
あるサイトを見てたら、”STATICFILES_DIRS = の記述あっても問題ない」ってかいてたから、自分で書いたソース含めていろいろと見てたら、以下みたいな記述が見つかったので試しに追加してみたら問題なかったです。
STATICFILES_DIRS = [BASE_DIR ]
またもう一つのやり方として、staticフォルダを作った上でGithubへプッシュした上ならば、STATICFILES_DIRSはHerokuの説明にあるとおりの記述でもデプロイは成功し、staticファイルの反映も問題なしでした。
ちなみにstaticファイルはローカルでcollectstaticを流したやつをGithubへPushすればできるんでしょうが、collectstaticはHerokuへのデプロイ処理時に自動的にやってくれるからそっちはまかせて、staticフォルダだけ作っとけば良いと思います。で、一点注意することがあるとすれば、Gitは空フォルダはPushしてくれないので、init.pyなどのからファイルを置いとく必要があることでしょう。
##で、結局どうするのか
###一番の問題点はこれ(ではないか)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Heroku公式の説明では「gzip機能(HTML要素を圧縮する機能らしい)を有効にしたい場合」に必要らしいので、そんな機能は使わないひとは設定してはいけません。(すると動きません)
公式の英語をよく理解しないままに書いてあるとおり何も考えず安易にSTATICFILE_STRAGEを追加してしまうとServer Error(500)になってしまいます。削除するとServer Error(500)は発生しないので根本原因はこいつではないかと思われます。
デプロイは成功するのにServer Error(500)になってしまって悩んでいる人は、とりあえずこいつを削除またはコメント化してみればいかがでしょうか。
上のスクリーンショットはクマ(別にサルでもイノシシでもUMAでもなんでもいいんです)を目撃した場所をGoogleMap上に記録することができるというやつです。アイコンに使った画像ファイルがちゃんと反映されているし地図表示や目撃座標にアイコンを設定するJavascriptが動いているので、staticフォルダが正しく認識し処理されているってことでしょう。
おなじみの管理サイトのデザインも正しく表示されてましたのでCSS参照も問題なし。
すでにテスト環境でSTATICFILES_STORAGEが設定されていて問題なく動いている場合は、whitenoise用への変更が必要みたいです。(gzip機能を使ってないので(設定がよくわからないので未確認)
Heroku+Django DEBUG=FalseでServer Error(500)が発生する問題の解決のために様々な人の様々な試みを書いたブログを読んでると、templateなどでstaticファイル自体の定義が正しくなかった(存在しないファイルを指定していた、存在場所が正しく指定されていなかった)というような意見もあり(ならばServer Errorじゃなくて表示されないだけなじゃないか?)、上のやり方で治らなかったら頑張って原因を見つけてください。そしてその結果を公開してください。
結論としては
###「Heoku公式はもっとわかりやすい日本語にしてくれたらいいな」と「自分の文章読解力をもっと疑え」
でした。
現場からは以上です。