Django: Static Image won't load

15,345

Solution 1

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()

Solution 2

  1. Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.
  2. In your settings file, define STATIC_URL, for example: STATIC_URL = 'static/'
  3. Hopes you stored images in folder projectname/static/appname/images/image.png
  4. Finally in your html simply add the following

<img src="appname/images/image.png" alt="My image"/>

please refer django dcumentation

Share:
15,345
rawa
Author by

rawa

Updated on June 09, 2022

Comments

  • rawa
    rawa almost 2 years

    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.

  • rawa
    rawa almost 9 years
    I had two issues with this: where is pattern defined/imported from and how do I correctly import settings.py into my urls.py (and which urls.py? The one that uses the template I'm guessing?)
  • rawa
    rawa almost 9 years
    Also I'm running this on my dev site
  • Matthew R.
    Matthew R. almost 9 years
    STATIC_ROOT is a parameter solely for collecting static files to look for in a production setting. I believe you are thinking of STATIC_URL, which is mentioned in OP's question.
  • Matthew R.
    Matthew R. almost 9 years
    To extend on this comment, see this link for how this is related to STATIC_URL and STATIC_ROOT.
  • rawa
    rawa almost 9 years
    Interesting, I ended up figuring this out myself (I updated my OP with my solution) and am wondering why I don't need to run the last bit of code appending a pattern onto urlpatterns. Thank you so much for clarifying everything else though!
  • erewok
    erewok almost 9 years
    That's good! I think that's because there is a view that is automatically enabled if you are running in DEBUG=True mode. The docs say you only need the urlpatterns, "To use the view with a different local development server...".