0

I'm writing a view that displays a set of images on a page.

This is the model

#models.py
class Movie(models.Model):
    title  = models.CharField(max_length = 500)
    poster = models.ImageField(upload_to = 'qanda/static/movie_posters')

#index.html
    <img src = "{{ STATIC_URL }}movie_posters/{{ movie.poster }}"></a>

When I runserver, the image doesn't appear. The URL the image is trying to load is

http://127.0.0.1:8000/static/movie_posters/qanda/static/movie_posters/image.jpg

When the URL it should be trying to load is

http://127.0.0.1:8000/static/movie_posters/image.jpg

My assumption is that since movie.poster is located at 'qanda/static/movie_posters', when I render it on HTML, it is loading the Static URL (127.0.0:8000/static) and then the location 'qanda/static/movie_posters' at the end. How do I make the image render correctly?

3 Answers 3

6

There are two pieces of how image url is calculated.

First in your settings.py you define MEDIA_ROOT. MEDIA_ROOT specifies an absolute folder on your computer where media will be stored. So for example for these settings:

MEDIA_ROOT = '/abs/path/to/media/'

and if you have a field

models.ImageField(upload_to='movie_posters')

then images will be stored at:

/abs/path/to/media/movie_posters/
/abs/path/to/media/movie_posters/poster.jpg <- example

This deals with where media is stored on your hard drive.

Second piece is how to calculate urls for these media files. For that you define MEDIA_URL in your settings.py. That essentially maps a URL to your MEDIA_ROOT location. So then if your MEDIA_URL is:

MEDIA_URL = 'http://localhost/media/'

Then if you want to access an image stored at movie_posters/poster.jpg which has an absolute path of /abs/path/to/media/movie_posters/poster.jpg, its URL should be http://localhost/media/movie_posters/poster.jpg. You can compute the URL by doing:

{{ MEDIA_URL }}{{ movie.poster }}

Please note that I am using MEDIA_URL instead of STATIC_URL. Those are not the same thing. Computing urls like that however is not very neat. Thats why Django's ImageField and FileField have an url attribute:

{{ movie.poster.url }}

Django will then compute the proper url depending on your MEDIA_URL setting.

Note:

For all of this to work, you have to have a separate media server running. Django does not serve any media files. In development it is only capable of serving static file (not same as media files). So in development one nice trick to serve media files is to use Python's simple web server. For that, open a new terminal (on Linux and Mac) or Command Prompt (on Windows) window/tab and navigate to your media folder. Then just execute the following command there:

python -m SimpleHTTPServer 8090

and make sure your setting is:

MEDIA_URL = 'http://localhost:8090/'

and then Python will serve your media files. That works nice for development.

Sign up to request clarification or add additional context in comments.

Comments

1

If you want to serve your media just using the development server you can add this for the time being to your urls.py

urlpatterns = patterns( ...all your awesome urls...) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Comments

0

you can define a custom template tag which returns the basename of the URL like this:

from django import template
import os

register = template.Library()

@register.filter
def getBasename(myURL):
   return os.path.basename(myURL)

this should go in your custom template tags (eg. customTemplateTags.py) file within your templatetags directory of your app.

Then you can use the filter in order to get only the image filename, not the entire URL.

{% load customTemplateTags %}
<img src = "{{ STATIC_URL }}movie_posters/{{ movie.poster.url|getBasename }}"></a>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.