1

Problem

I'm building a django web app. I can't get to display a static file (icon) in an html template when I run my app locally (ubuntu 20.04, python 3.8.5, django 3.1.4).

I DO NOT HAVE THIS ISSUE WHEN DEPLOYING ON HEROKU CLOUD, only on my localhost. When loading up the webpabe on my localhost, I can see "GET /static/icons/graph-up.svg HTTP/1.1" 404 1781 in the Django wsgi console.

My project tree:

django-project
|_ ...
|_ static
  |_ icons
    |_ graph-up.svg

index.html

{% load static %}
  <img src="{% static 'icons/graph-up.svg' %}" />

settings.py

[...]
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# I've tried with and without whitenoise, doesnt seem to change anything
MIDDLEWARE = [
  # 'django.middleware.security.SecurityMiddleware',
  'whitenoise.middleware.WhiteNoiseMiddleware',
  # ...
]

[...]

urls.py


urlpatterns = [

    path('', views.home, name='index'),
    ...

] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

I've followed the instructions from https://docs.djangoproject.com/en/3.1/howto/static-files/

Any ideas or suggestions welcome!

What I've tried locally so far

Without success (icon gets 404 error)

  • python manage.py runserver (to run with the wsgi from django)
  • gunicorn my_app.wsgi
  • heroku local (to simulate the heroku web server which is gunicorn locally)
  • python manage.py runserver --insecure (from Django Static files 404)
  • load the app locally with/without the whitenoise.middleware.WhiteNoiseMiddleware line in MIDDLEWARE after django.middleware.security.SecurityMiddleware

With partial success

Following an answer from Django Static files 404:

  1. I replaced:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

with:

STATIC_ROOT = ''
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join('static'), )
  1. I reloaded the wsgi and voila. The icon shows up.
  2. However when I revert back to the original
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

Just to see what happens, the icon still shows up.

Conclusion

I'm not sure this is the right thing to do but it seems to be working fine. Here's how I workaround the issue.

In my settings.py (for heroku):

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

In my settings_dev.py (for localhost):

STATIC_ROOT = ''
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join('static'), )
tamizboule
  • 511
  • 4
  • 8
  • 19
  • 1
    I am pretty sure heroku side, there is a `reverse proxy` for your djando app, while `python manage.py runserver` does not. if you can post your heroku config, that can help a bit. – tim Jan 06 '21 at 01:52
  • cheers @tim - Heroku cloud runs gunicorn my_app.wsgi. I've tried to run my app locally with gunicorn too and I still have the same problem. Sorry forgot to mention that, editing my question now. – tamizboule Jan 06 '21 at 15:26
  • Hey @tamizboule were you able to figure out a solution for this? Facing the exact same issue. Static files work well on Heroku but not on my localhost – Piyush May 02 '21 at 09:53

1 Answers1

0

I don't know exactly what the problem is but to fix it you can use Whitenoise module, used to serve staticfiles

for Reference: https://youtu.be/kBwhtEIXGII

for in detail info.: http://whitenoise.evans.io/en/stable/