7

I started with a django app and tried displaying an image in the home page. But the image is not getting displayed.

My settings.py:

MEDIA_ROOT = os.path.join(BASE_DIR,"media")
MEDIA_URL = "/media/"

My urls.py:

urlpatterns = patterns('',
# Examples:
# url(r'^$', 'myapp.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),

url(r'^admin/', include(admin.site.urls)),
url(r'',include('users.urls')),
) 

urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

My home.html:

<html>
    <head>
            <title>MY SITE</title>
    </head>
    <body>
            <img src="/media/image/myimage.jpg" alt="my image"/>
            Welcome to my site
    </body> 
</html>

I get the text my image displayed instead of the image

3
  • What is your BASE_DIR set to? Commented Dec 31, 2013 at 1:49
  • @dwightgunning: BASE_DIR = os.path.dirname(os.path.dirname(__file__)) Commented Dec 31, 2013 at 4:21
  • what version of django are you using? Commented Jan 3, 2014 at 5:00

4 Answers 4

16

ok, so I set up a simple 'paired-down' working example of this so no moving pieces were missing. Some Notes:

  • I used django 1.6
  • If you want to use a 'scale-able' delivery of static images you will want to follow the django-1.6 staticfiles documentation which is what this example provides.

This means that you need to hack-n-slash your MEDIA references. ( MEDIA is really meant for file upload's) and you dont need to fool with the staticfiles_urlpatterns in your urls.py file. As you get this behavior out-of-the box when you add 'django.contrib.staticfiles' to your settings.py

Overview: Here is what your file tree-layout will look like in django 1.6, and the file structure that I am referencing in this answer.

├── djproj
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py
└─── myapp
    ├── admin.py
    ├── __init__.py
    ├── models.py
    ├── static
    │   └── myapp
    │       └── myimage.jpg
    ├── templates
    │   └── index.html
    ├── tests.py
    └── views.py

Step 1: Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.

Step 2: In your settings file, define STATIC_URL, for example:

STATIC_URL = '/static/'

Step 3: change your home.html to look like this ( I used index.html in my example )

[ PROJECT_HOME/myapp/templates/index.html ]

<html>
<head>
        <title>MY SITE</title>
</head>
<body>
    {% load staticfiles %}
    <img src="{% static "myapp/myimage.jpg" %}" alt="My image"/>
        Welcome to my site
</body> 
</html>

Make sure to read the django-1.6 staticfiles documentation related to STATICFILES_STORAGE so you understand what these template tags are buying you. Hint: python manage.py collectstatic

Step 4: ( you may have already done this, but I did not see it) Make sure that TEMPLETE_DIRS is defined in your settings.py and includes your home.html ( key here is that django's template engine needs to be serving this as we will be using some template tags)

[ PROJECT_HOME/djproj/settings.py ]

TEMPLATE_DIRS = (
   # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
   # Always use forward slashes, even on Windows.
   # Don't forget to use absolute paths, not relative paths.
   BASE_DIR + '../myapp/templates',
)

Step 5: build a view that renders your home.html page.

[ PROJECT_HOME/myapp/views.py ]

from django.shortcuts import render_to_response

def index( request ):
   return render_to_response('index.html')

Since this is a bit convoluted, and there are several moving pieces here: here is a changeset that shows the complete 'changes'

You can of-coarse pull the entire github project if any of this is confusing. django-staticfiles-setupexample

Final Note: STATIC files were not always handled this way in django. The MEDIA dir used to be the settings attr you were after. So this answer is for Django 1.6 ( staticfiles were added in django version 1.3)( the directory layout was changed in django 1.5).

You can ( as you were trying to do) hardwire your media dirs to the STATIC defines. Altho I do-not recommend this. Which is why I did not describe how to do it this way.

3

You are adding the media urls too late in the list. Django will try to match each urlpattern in succession, stopping when it gets to the first one. In this case, it matches on r'' and doesn't get to the static files or the media urls.

You may be able to put each pattern in the single call to patterns(), instead of using +=. That would be the cleanest, but I can't test it here. A sure-fire way to do it would be to pull the "users.urls" line out and add it later, like so:

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
) 

urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += url(r'',include('users.urls'))
1
  • 2
    Anybody care to tell me why this keeps getting downvoted? I thought it was a decent answer. :( Commented Jan 26, 2014 at 16:01
3

I'd recommend you set DEBUG = TEMPLATE_DEBUG = True and request the image URL directly.

You'll get Django debug output either showing that the URL can't be matched or the file path it's actually looking for.

The settings look generally correct although you've not shared BASE_DIR which is important in this case.

2
  • Putting the URL gives me 404. and BASE_DIR = os.path.dirname(os.path.dirname(__file__)) Commented Dec 31, 2013 at 4:24
  • if you have debugging enabled you'll get much more useful output (on a clearly recognisable django debug template) than just a 404. Commented Dec 31, 2013 at 9:36
2

I had been struggling with the issue for like an entire day yesterday... I finally gave up and moved on creating my site without worrying about the images. Then today I decided to check the responsiveness of the site. I found out that my URLs were okay since I had strictly been following the documentation and best practices. The chrome console was saying:

Failed to load resource: net::ERR_BLOCKED_BY_CLIENT

The issue was with HTTP Referral Policy. Check them out. So after doing some research, this helped a lot, I found out that AdBlock was blocking my referred images. Apparently, my /media/ path was flagged in one of their regex patterns, deciding that my images were redirections to Ads. The ironic thing is that my website is about ads... so it must have heavily factored in, as my site has words like 'ad' in its url patterns. Long story short, I disabled AdBlock and my images now render. So I think it might be worth considering that even with best practices in your Django code, such an error could be caused by something with your browser!

Not the answer you're looking for? Browse other questions tagged or ask your own question.