I am using Django 1.3 with built-in static app.
My static folder structure is like this:
static/
css/
main.css
img/
js/
So I tried to reference images under static/css/img/
folder from CSS like this:
background:url('img/btn_white.gif') repeat-x;
But the images don'e show up. When I inspect elements in Chrome, I found the image path to be http://localhost/mysite/static/css/main.css/img/btn_white.gif/
Which is very wierd since this relative path should have referenced static/css/
folder instead of main.css
. So I tried to change path to be url('../img/btn_white.gif')
, and it works in Chrome and Firefox but not in IE.
I am pretty sure this problem is related to Django, because in my pure HTML/CSS, this relative path works just fine. I also tried to put css in media folder and the problem is the same.
My settings related to static app:
in settings.py:
STATIC_ROOT = os.path.join(os.path.dirname(__file__),'static').replace('\\','/')
STATIC_URL = 'http://localhost/mysite/static/'
in urls.py:
(r'^static/(?P<path>.*)/$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
Related question: Is a relative path in a CSS file relative to the CSS file?
The problem is caused by your URLconf, specifically the pattern:
r'^static/(?P<path>.*)/$'
This means that a the URL must end in a forward slash for it to match this pattern. i.e. the following URL will not match: (because it doesn't have a trailing slash)
/mysite/static/css/main.css
The weird thing, is that it does work. The reason for this is Django's APPEND_SLASH
setting:
When set to True, if the request URL does not match any of the patterns in the URLconf and it doesn't end in a slash, an HTTP redirect is issued to the same URL with a slash appended. Note that the redirect may cause any data submitted in a POST request to be lost.
So when your browser makes a request to:
/mysite/static/css/main.css
…Django will fail to match it against any of the URLs, and will issue a redirect to: (because APPEND_SLASH
defaults to True)
mysite/static/css/main.css/
This new request will succeed and your browser will now be able to download the CSS file, however the CSS file's resource URL now ends with a slash. When your browser processes the CSS rules and comes across:
background:url('img/btn_white.gif') repeat-x;
It will attempt to join that relative URI to the URI of the CSS resource. e.g.:
/mysite/static/css/main.css/ + img/btn_white.gif = /mysite/static/css/main.css/img/btn_white.gif
This will fail, so your browser will get a redirect to: (again because of APPEND_SLASH
)
/mysite/static/css/main.css/img/btn_white.gif/
But obviously that too will fail.
Change your URL pattern to the following: (note the removed trailing /
in the pattern)
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
Or use one of the recommended methods:
from django.conf import settings
if settings.DEBUG:
urlpatterns += patterns('django.contrib.staticfiles.views',
url(r'^static/(?P<path>.*)$', 'serve'),
)
…or:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ... the rest of your URLconf here ...
urlpatterns += staticfiles_urlpatterns()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With