Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Static Image won't load

I have been following the official documentation to the letter, trying some of the advice for related questions on here, and just searching the web in general and I am still having no luck getting one little image to load.

I have an image called 'logo.png' and my project hierarchy looks like this:

project/
   mysite/
      app/
         __init__.py
         admin.py
         models.py
         urls.py
         view.py
      mysite/
         __init__.py
         settings.py
         urls.py
         views.py
         wsgi.py
      static/
         logo.png
      templates/
         index.html
         calling_image.html

Inside settings.py I have STATIC_URL = '/static/'

Inside calling_image.html I have <img src="/static/logo.png">

My template calling_image.html is called by project/mysite/app/views.py which is of course then called on by project/mysite/app/urls.py and I even tried including the following two lines (as I saw suggested a few times) at the end of my urls.py:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()

Nothing works, so what have I done wrong?

Edit: Sorry I made a type, I have STATIC_URL = '/static/' with the closing slash in my settings.py and for clarification, I am running this on my dev build with python manage.py runserver

Solved: So I ended up solving this myself. I created a directory resources within project/mysite/ and placed logo.png in there. I then set STATICFILES_DIRS = (os.path.join(BASE_DIR, "resources"),) and ran collecstatic and everything worked! Didn't need to use urlpatterns += staticfiles_urlpatterns() and whatnot.

like image 217
rawa Avatar asked Jul 15 '15 03:07

rawa


1 Answers

It looks like you probably need the variable STATICFILES_DIRS defined in your settings.py and that should include the location of that static directory holding logo.png.

Django only looks for static files inside a static directory inside each app by default. If you have a static file outside of any app, it won't be picked up by collectstatic automatically.

See https://docs.djangoproject.com/en/1.8/ref/settings/#std:setting-STATICFILES_DIRS


Confusion Surrounding Staticfiles

There's always a lot of confusion around Django and Static files. I believe this confusion comes from the fact that it doesn't make any sense for Django to handle static files in production, but it seems natural to use it when learning to use Django and thus when initially developing.

The reason it doesn't make any sense for Django to serve static files is that Django is a framework for rendering dynamic responses. "Static" files are not dynamic: they don't change. Thus, it's a huge waste of resources to spin up a Python application, which calls all of the Django machinery, just to find and return a file that has no dynamic content.

Staticfiles: the job of the webserver

There is something that is really good at serving static files: webservers themselves (such as a Apache, nginx, etc.). That's what they were designed to do. The webserver can run a Python/Django application or it can just locate a file and send it back, so you typically configure a webserver by telling it something like the following (in pseudo-server-speak):

  • When someone accesses the path /static/ let them access the files in the following directory: /var/www/static/.

  • When someone accesses the path /, spin up this Python application that lives over here: /var/www/django-app.

Django Static Files Tools

As a result, Django comes with some helper tools that manage static files, so that your actual server can serve them.

These tools are the following(defined in settings.py):

  • STATIC_URL: the URL path where your server will be serving your static files. This is just so that when you use the static templatetag, that Django knows how to urlreverse it. In other words, it's merely a convenient way of turning {% static "..." %} into /static/....
  • STATIC_ROOT: the place on your server (or in the cloud somewhere), to which Django will copy your static files, so that your server can serve them. This copying happens when you run collectstatic.
  • STATICFILES_DIRS: any extra directories Django should look for static files whenever you run collectstatic. By default Django only looks in each app's directory for a static directory (just like with templates).

Static Files In Development

Okay, but that's not so helpful in development where you are probably using Django's runserver command. You don't have a server running that will server static files.

Thus, you can ask Django to please also server static files for you in just this one case, because you are developing your application and don't want to run a separate server.

There is a view that automatically should pick up and serve static files when DEBUG=True. Alternately, this is also why someone might use the following:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
like image 149
erewok Avatar answered Oct 08 '22 17:10

erewok