頭の中は異空間

ものづくり中心

【Django】heroku local実行時にstaticファイルが必ず404になる件

今回からはてな記法に変えてみました。コードにシンタックスハイライトを楽につけるにはこうするしかなかったのです。

Djangoでstaticファイルをただ読み込ませるというだけの単純なはずの作業で数日間大苦戦したので、このような邪悪は処罰しようと思い、後学のために残しておきます。

環境(執筆時)

Djangoのファイル構成

f:id:notwo:20190907160308p:plain
白枠はプロジェクト名の箇所です。アプリ名をuser_authとしています。

python manage.py startapp user_auth

でアプリ作成しました。
staticディレクトリがアプリ直下と、project_staticディレクトリがプロジェクト直下にそれぞれ配置されているのがわかると思います。
project_staticディレクトリには本番にデプロイする際にstaticファイルを配置するために必要なので今のうちに作ってしまいます。ここではローカルでの動きについてのみ触れますので、実際には使いませんが。

コード

以下でuser_auth/css/bootstrap.min.cssを読み込もうとしています。

アプリ名/base.html

{% load static %}

...

<link href="{% static 'user_auth/css/bootstrap.min.css' %}" rel="stylesheet">

settings.py

PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
STATIC_ROOT = os.path.join(BASE_DIR, 'project_static')
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

このように設定してpython manage.py runserverとすると、404が出ずstatic以下のファイルが読み込まれます。実際にChromeで開発者ツール(F12)→Sourceとするとそこに読み込んだファイルが有ることでしょう。
手元で普通にDjangoの開発をするだけならこれで十分です。
ここまでの構造やコードについての解説は以下記事が大変優秀でした。
hideharaaws.hatenablog.com


しかし問題は、herokuと組み合わせる場合。全く同じディレクトリ構成とコードでheroku local web実行後に結果を見て見ると…
f:id:notwo:20190907161514p:plain
なんでじゃ。
heroku local webだと参照している場所が違うのか…?Djangoでは思想?として開発中とデプロイ時では参照の仕方が違うことはわかりました。
↓ここでよく解説されています。
qiita.com

しかし同じローカルで実行しているのに同じことができないのは不思議です。散々探し回っても解決に至る情報にはたどり着きませんでした。というわけで、ローカル開発するならrunserverを実行するのが確実なのでそっちにします。何か変わるわけでもなさそうですしね。というわけでheroku localコマンドには永久にご退場願おうか。

本番にデプロイするときは以下公式サイトを見れば良さそうです。
devcenter.heroku.com
ここによればpython manage.py collectstaticしろと書いてあります。実際にやってみると、各アプリのcssとかjsがproject_static以下に集約されることがわかります。元あるファイルからコピーしただけなので、アプリ直下のstaticの中身はそのままですね。おそらく、static以下のファイルに修正が入ったらこのコマンドを毎回実行する必要がありそうです。



技術系の記事だと最近Qiitaに垢を作ったのでそっちに書こうか迷ったのですが、個人的にはこのブログを盛り上げて行きたい思いがあるので、基本的に今後もここに載せていくつもりです。そもそも更新頻度も高くないし。