Images and Stylesheets

2 views
Skip to first unread message

Greg Lindstrom

unread,
Apr 11, 2008, 10:19:59 PM4/11/08
to django...@googlegroups.com
Hello Everyone-

I started learning Django at PyCon in Chicago and have worked most of the way through the "Django Book" and Sams "Teach Yourself Django", as well as "Head First HTML with CSS and XHTML".  It's been quite a lot for this old dog, but I'd like to take a crack a writing my own web site using Django.  I have two problems, and I think they are related.  The first is how to get images in my site and the next is how to use css.

I wrote Jacob about images and he was kind enough to point me to documentation on how to get the web server to "serve" the images.  I hate to put it this bluntly, but I don't know what that means (I've been programming database applications for 20 years and all this web stuff is still pretty new to me).  Is there something that explains to someone like me how to get images into the site?  Though I'm running Django on my Ubuntu laptop, I would like to eventually have it hosted.  I would like to know how to "do" images locally, then what I need to do when I host my site.

The other problem is getting css to work with my site.  I have set up a base.html template (I love the templates, thank-you) and extend it with other templates, call one greg.html.  The html generates just as I expect it to (overriding blocks just as it should), but it doesn't "see" the style sheet.  One it gets "in" the template I'm OK; the "Head First" book did a pretty good job explaining it.  I even put a syntax error in my view  so Django would list out the settings, but couldn't find where Django is looking for the css file.  I suspect it is a similar problem to the images, but I just don't know.


Thanks for your help,

--greg

Justin Lilly

unread,
Apr 11, 2008, 10:29:51 PM4/11/08
to django...@googlegroups.com
You're problems are one and the same. It seems you're runserver isn't configured to serve images. The bit of code you're looking for is:

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

where /site_media/* is the path of your files. So if you have master.css that lives in a css folder in /path/to/media, you'd reference it as:

/site_media/css/master.css

similarly, if you have an img directory under site_media, you would reference your images to /site_media/img/foo.jpg

You will also want to look into setting up the MEDIA_URL for your settings.py file. I would suggest:  'http://localhost:8000/site_media/'

Now instead of referring to your css file as:

/site_media/css/master.css

you can now refer to it as

{{ MEDIA_URL }}css/master.css

which should ease the pain of migration when your media might not live in /site_media/


I'm not sure if you were asking but "Serving static media" basically means "Tell runserver it can find my images _HERE_" where _HERE_ is defined in the code snippet above.

Hop on by #django on irc.freenode.net if you have any more problems (or just reply here).

-justin
--
Justin Lilly
Web Developer/Designer
http://justinlilly.com

Tim Chase

unread,
Apr 11, 2008, 10:56:22 PM4/11/08
to django...@googlegroups.com
> I started learning Django at PyCon in Chicago and have worked
> most of the way through the "Django Book" and Sams "Teach
> Yourself Django", as well as "Head First HTML with CSS and
> XHTML". It's been quite a lot for this old dog, but I'd like
> to take a crack a writing my own web site using Django.

welcome aboard!

> I have two problems, and I think they are related.

They are indeed

> to documentation on how to get the web server to "serve" the
> images. I hate to put it this bluntly, but I don't know what
> that means

To "serve" simply means that the web-server (usually Apache or
lighttpd) listens for requests for files and responds by
"serving" them. An example might be

C: GET /blog/2008/3/14/my-pi-day-post HTTP/1.1
C: Host: www.example.com
S: HTTP/1.1 200 OK
S: Date: Mon, 23 May 2005 22:38:34 GMT
S: Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
S: Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
S: Etag: "3f80f-1b6-3e1cb03b"
S: Accept-Ranges: bytes
S: Content-Length: 438
S: Connection: close
S: Content-Type: text/html; charset=UTF-8
S:
S: <html><body>My first blog page</body></html>

(C = client/webbrowser, S = server).

It may be helpful to learn some rudimentary HTTP (the protocol
over which all of this is being served).

http://en.wikipedia.org/wiki/HTTP

Or at least install the "Live HTTP Headers" FireFox extension
that allows you to watch/record the HTTP transactions. But the
basic gist is that your browser requests a page; the server
"serves" this page (dynamically, created by via Django). Your
browser then sees references to other external files (images,
CSS, JavaScript, etc) and makes requests for each of these. The
server receives each request and returns ("serves") the requested
content--an image, a CSS file, a JavaScript file, or even
additional dynamic content from another Django source.

> I would like to know how to "do" images locally, then what I
> need to do when I host my site.
>
> The other problem is getting css to work with my site.

Both images and CSS files (as well as JavaScript source files,
when you get there) are considered "static media".

Django's development server can serve these static media files.
I like to use the following in my urls.py file:

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

This allows me to serve media from the development server (which
get put in the directory specified by MEDIA_ROOT), but it
doesn't alter my urlpatterns in production where the actual
web-server handles serving media. To move to production, you'll
want to configure your server (likely Apache or lighttpd) to
serve these static files. The server is very good at serving
static (non-dynamic content), so it's best to let it handle these
files. Django *can* handle them, but it's not designed to do as
much (it's designed to serve dynamic content). There's a good
writeup at

http://www.djangoproject.com/documentation/static_files/

regarding how to configure your web-server (Apache or lighttpd)
for serving these static files outside of Django.

Hopefully this gives you some hints, pointers in the right
direction, terminology to search the web, and tips in general to
get things working. As always, the list is a pretty friendly
place, and will try and help guide you.

-tim


Doug Van Horn

unread,
Apr 11, 2008, 11:08:48 PM4/11/08
to Django users
Here's my rewording of your question:

"How do I serve static content?"

Websites need to serve up your HTML, CSS, JavaScript, and images.

In Django, your views are serving up your HTML. What you need to do
is serve up the rest of that stuff.

The first way to serve static content, when you are using the Django
development server, is to use the 'django.views.static.serve' view.
You'll find it documented here:

http://www.djangoproject.com/documentation/static_files/

Here's the gist, as you might include it in your urls.py:

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

Then, in your HTML files, you might include CSS and image files via
the following:

<link rel="stylesheet" href="/static/style.css" />
and
<img src="/static/foo.png" alt="Cool foo image." />

A more 'correct' way might look like this:

<link rel="stylesheet" href="{{ MEDIA_URL }}css/style.css" />

Note that MEDIA_URL gets included as a template variable when you use
the 'django.core.context_processors.media' template context processor
and pass a RequestContext to your template rather than a regular
Context.

When you get around to deploying into an Apache environment, you'll
need to either run a second 'media' server (think 'media.example.com'
virtual host) or you can turn off python handling for certain
locations under your app host and serve up the static files. Consult
your Apache docs for more info (specifically, the Location, Directory,
and Alias directives). If you're deploying against lighttpd I would
guess the concepts are similar.

I guess you don't actually /need/ to serve up your static content via
Apache, the above urls.py entry will work fine under Apache. It's
more a matter of you /should/ (see the static_files link, they give a
better explanation...).

Hope this helps.

--
Doug Van Horn
http://maydigital.com/

andy baxter

unread,
Apr 12, 2008, 4:08:45 AM4/12/08
to django...@googlegroups.com
The basic point here is that while django is good for generating dynamic
pages which are created in code from a database, it's not so good (quick
/ reliable / secure) for just serving static pages that don't change. So
the preferred solution is to have django do the bit it's good at, and
use a standard webserver to do the static pages (including images and
css). There is a django module for serving static content, but the docs
say this should only be used during development, not in your final site.

greg

unread,
Apr 12, 2008, 8:29:38 PM4/12/08
to Django users
Thanks to everyone for the replies. Static content now makes sense to
me, and I have things up and working.

--greg

Reisswolf

unread,
Apr 15, 2008, 6:34:09 AM4/15/08
to Django users
I have followed Doug Van Horn's detailed explanation very closely. I
have also read the Django documentation page on this particular
topic. But for some reason, I still cannot get the thing to work.

Here is my situation: In my <full path>/Programming/Python/Django
directory I have created a project called TestProject, and in
TestProject I have an app called TestApp.

Also in TestProject I have Media/JavaScript/MyJSFile.js. In urls.py I
have the following line:

(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '<full path>Programming/Python/Django/TestProject/
Media'}),

I have also specified '<full path>/Programming/Python/Django/
TestProject/Media' as my MEDIA_ROOT and '/media/' as MEDIA_URL in
settings.py. I have read the documentation very carefully, and I
believe I am doing everything correctly.

I have <script type="text/javascript" src="media/JavaScript/
MyJSFile.js"></script> in the <head> tag of my template. Everything
else in the template gets rendered, but the JavaScript part does not.
In fact, I get an error saying "TestFunc() not defined." (TestFunc()
is a simple hello-world function defined in MyJSFile.js.)

I am really at my wit's end. If someone here notices my error, I
would be very grateful to him for pointing it out to me.

*****

In case it might be important, I should mention that I am using Fedora
8, and I installed Django through yum: yum install Django.

*****

Thanks in advance for your help,

Duke

unread,
Apr 15, 2008, 6:49:44 AM4/15/08
to Django users

change the URL config as

from django.conf.urls.defaults import *
import os
ROOT_PATH = os.path.dirname(__file__)

urlpatterns = patterns('',
# Example:
(r'^hellodojo/', 'hello.views.hellodojo'),
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': ROOT_PATH + '/site_media/'}),

the site_media is the floder contain the image and CSS file
site_media should be in the floder that hold the project.
i had this problem three days a go now i have solved by config the URL

Thanks
Duke

Reisswolf

unread,
Apr 15, 2008, 8:33:43 AM4/15/08
to Django users
Hi,

Sorry to bother everyone again, but the suggestion above is not
working either.

Actually, I fail to see why the ROOT_PATH suggestion would work when
hard-coding the path document_root is not working. But that could
just as well be due to my ignorance.

I have tried the ROOT_PATH suggestion. I have tried everything else I
could think of. If anyone has any more suggestions, I would be very
grateful.

Karen Tracey

unread,
Apr 15, 2008, 9:51:15 AM4/15/08
to django...@googlegroups.com
On Tue, Apr 15, 2008 at 6:34 AM, Reisswolf <reis...@gmail.com> wrote:

I have followed Doug Van Horn's detailed explanation very closely.  I
have also read the Django documentation page on this particular
topic.  But for some reason, I still cannot get the thing to work.

Here is my situation:  In my <full path>/Programming/Python/Django
directory I have created a project called TestProject, and in
TestProject I have an app called TestApp.

Also in TestProject I have Media/JavaScript/MyJSFile.js.  In urls.py I
have the following line:

(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '<full path>Programming/Python/Django/TestProject/
Media'}),

I have also specified '<full path>/Programming/Python/Django/
TestProject/Media' as my MEDIA_ROOT and '/media/' as MEDIA_URL in
settings.py.  I have read the documentation very carefully, and I
believe I am doing everything correctly.

I have <script type="text/javascript" src="media/JavaScript/

You are missing a leading slash before media in your src= here.  Without it the browser will request a url relative to the page you are providing (take a look at the GETs printed out by the dev server when you request the page), but your url spec for the static server requires that the 'media/' be at the beginning of the requested url.  So what you have will only work when you are serving the root page. 

Karen

Duke

unread,
Apr 15, 2008, 10:46:46 AM4/15/08
to Django users

This is strange its work for me

U config the URL as i suggested and referce the image as below in the
<img>tab
<img src="/site_media/pic.jpg">
This should definitly work it even work for javascript.
Thank
Duke

Doug Van Horn

unread,
Apr 15, 2008, 3:35:28 PM4/15/08
to Django users
Your previous description sounds pretty close. Check your URLs in
your HTML (mentioned by Karen Tracey in this thread).

As a quick reference, here are the relevant entries in my settings.py:

import os
ROOT_DIR = os.path.normpath(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(ROOT_DIR, 'media')
MEDIA_URL = '/media/'
ADMIN_MEDIA_PREFIX = '/admin-media/'


and the relevant entry in my urls.py:

import settings
urlpatterns += patterns('',
(r'^%s(.*)$' % settings.MEDIA_URL[1:],
'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
)


The only relevant thing to note based on your earlier post would be
that '/media/' is by default used by the ADMIN_MEDIA_PREFIX setting.
Perhaps the 'media' URL is experiencing some stompage...

Also, forget about the whole HTML page for now and try and pull up
your static media directly in your browser:

http://localhost:8000/media/JavaScript/MyJSFile.js

Check the output of the dev server when hitting that URL, maybe it'll
be helpful in telling you what's going on...


fwiw.

Reisswolf

unread,
Apr 16, 2008, 5:12:17 AM4/16/08
to Django users
>> The only relevant thing to note based on your earlier post would be
that '/media/' is by default used by the ADMIN_MEDIA_PREFIX setting.
Perhaps the 'media' URL is experiencing some stompage... <<

Hi Doug,

For pointing out the above pitfall, I would personally like to pay for
your plane ticket to Sweden to collect your Prize later this year!

That, folks, was the problem! Since "/media/" was also specified in
the admin section by default, my specification was being overridden.
I have renamed my URL to site_media, and now everything is working!

Thanks a lot to everyone for taking time to help me out.

Best wishes,

Amit
Reply all
Reply to author
Forward
0 new messages