How do I include image files in Django templates?

Viewed 232469

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?

13 Answers

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.

Your

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

will work for a HTML file read from disk, as it will assume the URL is file:///home/.... For a file served from a webserver though, the URL will become something like: http://www.yourdomain.com/home/tony/london.jpg, which can be an invalid URL and not what you really mean.

For about how to serve and where to place your static files, check out this document. Basicly, if you're using django's development server, you want to show him the place where your media files live, then make your urls.py serve those files (for example, by using some /static/ url prefix).

Will require you to put something like this in your urls.py:

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

In production environment you want to skip this and make your http server (apache, lighttpd, etc) serve static files.

I've had the hardest time figuring this out so I am making this post to explain as clearly as i can, what worked for me, to help someone else.

Let's say you have a project called project_name. and an app called app_name. your root directory should look like this:

/app_name
/project_name
manage.py

DEVELOPMENT.

while in development mode, your CSS and JS files should be inside ./app_name/static/app_name/..

however your images should be inside ./app_name/static/media/..

now add these to settings.py :

If this not already there, add

    STATIC_URL = '/static/' 

This tells Django where to find all the static files.

    MEDIA_URL = '/media/'

This points Django to the folder where your images are, after it loads static. In this case it is /media/ because our images are in /static/media.

next, you should put this in the individual template where you need the image(i thought putting a single {% load static%} in the general layout.html template would suffice, it didn't):

    {% load static %}

    <img src="{% static image_name %}>

depending on how you set up your project, image_name could be the exact name of the image file like "image.jpg", a variable for an image field like user.image etc

lastly, go into the project_name urls.py (same folder as settings.py) and add this line to the end:

    from django.conf import settings
    from django.conf.urls.static import static


    if settings.DEBUG:
        urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

basically telling Django to use a work around so you can see use the images in development.

That is all. your project will now display images while you are writing and testing your code(development)

PRODUCTION.

When you want to deploy your project, there are some extra steps you need to take.

Because Django does not serve images as static files during production, you have to install a Middleware called Whitenoise.

http://whitenoise.evans.io/en/stable/#installation

    pip install whitenoise

Then add the following to settings.py:

look for MIDDLEWARE and add just under django.middleware.security.SecrutiyMiddleware:

    'whitenoise.middleware.WhiteNoiseMiddleware',

Next we have to define our paths, this is because in production Django will basically collect all the static files from all our apps and rearrange them in a single folder.

Add the following to settings.py:

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

This tells Django where to put static files when it collects them. In this case we are telling Django to put the files in the root folder. so after collectstatic runs our app would look like

/app_name
/project_name
/static
manage.py

Then add:

 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

This tells django where to put files that a user who on our site uploads..

Next,we want to go up and change Debug to False.

    Debug = False

Debug mode is used for testing in development, and in production you don't want your app displaying error codes and the names of files and lines where something went wrong. potential security threat. Once you turn debug mode to false, Django changes how it serves the static files. so ordinarily, if you were to run your app now, you won't see the images..

with these done, now you are ready for production. to test that everything is okay, you can run:

    python manage.py collectstatic

(type yes if prompted) Django will collect all the static files and arrange them as necessary. if you run your project now, with debug still turned off you should see your images. you can even now delete the individual static folders in app_name or any other apps you have, if you want because Django will not use them in production. Once debug is off, Django only uses static from the collected static folder. You can now deploy your project

If you give the address of online image in your django project it will work. that is working for me. You should take a shot.

Also check that the problem may not be due to path, but file name or extension. While failing to dislay an image added to base.html template, the error was found related to image file extension. If you are storing the image in jpeg format, use .jpg as the extension in the img tag <img src="{% static 'logo.jpg' %}" alt="Logo">.

Related