使用相对路径在CSS中引用图像在Django中不起作用

Yif*_*ifu 8 django django-static

我正在使用内置静态应用程序的Django 1.3.

我的静态文件夹结构是这样的:

static/
    css/
       main.css
       img/
    js/
Run Code Online (Sandbox Code Playgroud)

所以我尝试static/css/img/从CSS中引用文件夹下的图像,如下所示:

background:url('img/btn_white.gif') repeat-x;
Run Code Online (Sandbox Code Playgroud)

但图像不会出现.当我检查Chrome中的元素时,我找到了图像路径http://localhost/mysite/static/css/main.css/img/btn_white.gif/

这是非常奇怪的,因为这个相对路径应该有引用static/css/文件夹而不是main.css.所以我尝试改变路径url('../img/btn_white.gif'),它适用于Chrome和Firefox,但不适用于IE.

我很确定这个问题与Django有关,因为在我的纯HTML/CSS中,这个相对路径运行得很好.我也尝试将css放在媒体文件夹中,问题是一样的.

我的设置与静态应用相关:

在settings.py中:

STATIC_ROOT = os.path.join(os.path.dirname(__file__),'static').replace('\\','/')
STATIC_URL = 'http://localhost/mysite/static/'
Run Code Online (Sandbox Code Playgroud)

在urls.py中:

(r'^static/(?P<path>.*)/$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
Run Code Online (Sandbox Code Playgroud)

相关问题:CSS文件中的相对路径是否相对于CSS文件?

bra*_*ers 9

问题是由您的URLconf引起的,特别是模式:

r'^static/(?P<path>.*)/$'
Run Code Online (Sandbox Code Playgroud)

这意味着URL 必须以正斜杠结尾才能匹配此模式.即以下URL 不匹配 :(因为它没有尾部斜杠)

/mysite/static/css/main.css
Run Code Online (Sandbox Code Playgroud)

奇怪的是,它确实有效.原因是Django的APPEND_SLASH设置:

设置为True时,如果请求URL与URLconf中的任何模式都不匹配,并且不以斜杠结尾,则会向相同的URL发出HTTP重定向,并附加斜杠.请注意,重定向可能导致POST请求中提交的任何数据丢失.

因此,当您的浏览器发出请求时:

/mysite/static/css/main.css
Run Code Online (Sandbox Code Playgroud)

... Django将无法将其与任何URL匹配,并将发出重定向到:(因为APPEND_SLASH默认为True)

mysite/static/css/main.css/
Run Code Online (Sandbox Code Playgroud)

这个新请求将成功,您的浏览器现在可以下载CSS文件,但CSS文件的资源URL现在以斜杠结尾.当您的浏览器处理CSS规则并遇到时:

background:url('img/btn_white.gif') repeat-x;
Run Code Online (Sandbox Code Playgroud)

它将尝试将该相对URI加入CSS资源的URI.例如:

/mysite/static/css/main.css/ + img/btn_white.gif = /mysite/static/css/main.css/img/btn_white.gif
Run Code Online (Sandbox Code Playgroud)

这将失败,因此您的浏览器将重定向到:(再次因为APPEND_SLASH)

/mysite/static/css/main.css/img/btn_white.gif/
Run Code Online (Sandbox Code Playgroud)

但显然也会失败.

解决方案

将您的URL模式更改为以下内容:(请注意/ 模式中删除的尾随)

(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
Run Code Online (Sandbox Code Playgroud)

或者使用推荐的方法之一:

from django.conf import settings

if settings.DEBUG:
    urlpatterns += patterns('django.contrib.staticfiles.views',
        url(r'^static/(?P<path>.*)$', 'serve'),
    )
Run Code Online (Sandbox Code Playgroud)

…要么:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

# ... the rest of your URLconf here ...

urlpatterns += staticfiles_urlpatterns()
Run Code Online (Sandbox Code Playgroud)