How do I include image files in Django templates?

I'm new to Django and I'm trying to learn it through a simple project I'm developing called 'dubliners' and an app called 'book'. The directory structure is like this:

dubliners/book/  [includes models.py, views.py, etc.]
dubliners/templates/book/

I have a JPG file that needs to be displayed in the header of each Web page. Where should I store the file? Which path should I use for the tag to display it using a template? I've tried various locations and paths, but nothing is working so far.

...

Thanks for the answer posted below. However, I've tried both relative and absolute paths to the image, and I still get a broken image icon displayed in the Web page. For example, if I have an image in my home directory and use this tag in my template:

<img src="/home/tony/london.jpg" /> 

The image doesn't display. If I save the Web page as a static HTML file, however, the images display, so the path is correct. Maybe the default Web server that comes with Django will display images only if they're on a particular path?


Try this,

settings.py

# typically, os.path.join(os.path.dirname(__file__), 'media')
MEDIA_ROOT = '<your_path>/media'
MEDIA_URL = '/media/'

urls.py

urlpatterns = patterns('',
               (r'^media/(?P<path>.*)$', 'django.views.static.serve',
                 {'document_root': settings.MEDIA_ROOT}),
              )

.html

<img src="{{ MEDIA_URL }}<sub-dir-under-media-if-any>/<image-name.ext>" />

Caveat

Beware! using Context() will yield you an empty value for {{MEDIA_URL}}. You must use RequestContext(), instead.

I hope, this will help.


In production, you'll just have the HTML generated from your template pointing to wherever the host has media files stored. So your template will just have for example

<img src="../media/foo.png">

And then you'll just make sure that directory is there with the relevant file(s).

during development is a different issue. The django docs explain it succinctly and clearly enough that it's more effective to link there and type it up here, but basically you'll define a view for site media with a hardcoded path to location on disk.

Right here.


I do understand, that your question was about files stored in MEDIA_ROOT, but sometimes it can be possible to store content in static, when you are not planning to create content of that type anymore.
May be this is a rare case, but anyway - if you have a huge amount of "pictures of the day" for your site - and all these files are on your hard drive?

In that case I see no contra to store such a content in STATIC.
And all becomes really simple:

static

To link to static files that are saved in STATIC_ROOT Django ships with a static template tag. You can use this regardless if you're using RequestContext or not.

{% load static %} <img src="{% static "images/hi.jpg" %}" alt="Hi!" />

copied from Official django 1.4 documentation / Built-in template tags and filters


In development
In your app folder create folder name 'static' and save your picture in that folder.
To use picture use:

<html>
    <head>
       {% load staticfiles %} <!-- Prepare django to load static files -->
    </head>
    <body>
        <img src={% static "image.jpg" %}>
    </body>
</html>

In production:
Everything same like in development, just add couple more parameters for Django:

  1. add in settings.py
    STATIC_ROOT = os.path.join(BASE_DIR, "static/")(this will prepare folder where static files from all apps will be stored)

  2. be sure your app is in INSTALLED_APPS = ['myapp',]

  3. in terminall run command python manage.py collectstatic (this will make copy of static files from all apps included in INSTALLED_APPS to global static folder - STATIC_ROOT folder )

    Thats all what Django need, after this you need to make some web server side setup to make premissions for use static folder. E.g. in apache2 in configuration file httpd.conf (for windows) or sites-enabled/000-default.conf. (under site virtual host part for linux) add:

    Alias \static "path_to_your_project\static"

    Require all granted

    And that's all


I have spent two solid days working on this so I just thought I'd share my solution as well. As of 26/11/10 the current branch is 1.2.X so that means you'll have to have the following in you settings.py:

MEDIA_ROOT = "<path_to_files>" (i.e. /home/project/django/app/templates/static)
MEDIA_URL = "http://localhost:8000/static/"

*(remember that MEDIA_ROOT is where the files are and MEDIA_URL is a constant that you use in your templates.)*

Then in you url.py place the following:

import settings

# stuff

(r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}),

Then in your html you can use:

<img src="{{ MEDIA_URL }}foo.jpg">

The way django works (as far as I can figure is:

  1. In the html file it replaces MEDIA_URL with the MEDIA_URL path found in setting.py
  2. It looks in url.py to find any matches for the MEDIA_URL and then if it finds a match (like r'^static/(?P.)$'* relates to http://localhost:8000/static/) it searches for the file in the MEDIA_ROOT and then loads it