5

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

Aswin Murugesh
  • 10,831
  • 10
  • 40
  • 69

4 Answers4

15

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.

Jeff Sheffield
  • 5,768
  • 3
  • 25
  • 32
2

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'))
bonsaiviking
  • 5,825
  • 1
  • 20
  • 35
2

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.

Dwight Gunning
  • 2,485
  • 25
  • 39
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!

karuoro
  • 541
  • 4
  • 12