关于python:Django:你如何提供媒体/样式表并在模板中链接到它们

Django: how do you serve media / stylesheets and link to them within templates

这个问题的变体已经被提出,但是在呈现模板时,我仍然无法正确地加载样式表。

我正试图在开发过程中为Django过程中的静态媒体提供服务,我知道这在生产中是非常不受欢迎的。我将发布我的配置和模板,希望有人能帮助我了解哪里出错了。

请注意,我确实尝试在Django项目网站上遵循这个示例,但是它没有提到如何从模板引用样式表。我还尝试了许多不同的变化,同样的事情,所以我的代码/设置可能有点偏离描述。

设置.py

1
2
3
MEDIA_ROOT = 'D:/Dev Tools/django_projects/dso/media'
MEDIA_URL = '/media/'
ADMIN_MEDIA_PREFIX = '/media/'

网址.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.conf.urls.defaults import *
from django.conf import settings
from django.contrib import admin

admin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/(.*)', admin.site.root),
    (r'^ovramt/$', 'dso.ovramt.views.index'),
)

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

在我的模板中:

1
2
3
4
5
<head>
 {% block title %} DSO Template {% endblock %}  
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<link rel="stylesheet" type="text/css" href="../media/styles.css">
</head>

我向您保证,文件(模板/媒体)在我的文件系统上的正确目录中。如果我需要提供任何额外的信息,请发表评论。

编辑:

我遇到的一个问题是在链接前使用了一个'/'。如果正斜杠是预先准备好的,那么链接将从站点的根目录打开。如果没有正斜杠,链接将在当前级别打开。一个例子:

www.example.com/application/有一个链接"/app2/和一个链接"app3/"。APP2将在www.example.com/app2/打开,APP3将在www.example.com/application/app3/打开。我想这让我很困惑。


我只是自己想出来。

设置.py:

1
2
3
MEDIA_ROOT = 'C:/Server/Projects/project_name/static/'
MEDIA_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/media/'

网址.py:

1
2
3
4
5
6
from django.conf import settings
...
if settings.DEBUG:
    urlpatterns += patterns('',
        (r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
    )

模板文件:

1
<link rel="stylesheet" type="text/css" href="/static/css/style.css" />

文件位于此处:

1
"C:/Server/Projects/project_name/static/css/style.css"


Django已经有了媒体URL的上下文处理,请参阅Django的文档。

默认情况下,它应该在requestContext中可用(除非您已经定制了上下文处理器并且忘记添加它)。


我通常把我自己的模板简单标记,因为django没有提供css/javascript文件。Apache会这样做,所以我的媒体URL通常是http://static.mysite.com。

yourapp/templateTags/media_url.py:

1
2
3
4
5
6
7
from django.template import Library
from yourapp.settings import MEDIA_URL
register = Library()

@register.simple_tag
def media_url():
    return MEDIA_URL

在我的模板文件中:

1
2
{% load media_url %}
<link href="{{ media_url }}css/main.css" rel="stylesheet" type="text/css">

您还可以制作自己的上下文预处理器,以便在每个模板中添加媒体URL变量。


我只是使用绝对命名。除非你是在一条很深的道路上运行这个站点(或者即使你是),否则我会把..掉下来,去做如下的事情:

1
<link rel="stylesheet" type="text/css" href="/media/styles.css">

只是觉得我会很快插话。虽然这里的所有建议都很好,我在开发时确实使用了Ty的例子,但一旦进入生产阶段,您可能会选择通过直接的Apache或使用的其他服务器来提供文件。

我要做的是在开发完成后设置一个子域,并替换所有到静态媒体的链接。例如:

1
<link rel="stylesheet" type="text/css" href="http://static.mydomain.com/css/style.css" />

这样做的原因有两方面。首先,看起来让Django在不需要的时候处理这些请求会比较慢。第二,由于大多数浏览器实际上可以同时从3个不同的域下载文件,因此对静态文件使用第二个子域实际上会加快用户的下载速度。


我有几个主意,我不知道哪一个对我有用:)

Make sure to use a trailing slash, and to have this be different from the MEDIA_URL setting (since the same URL cannot be mapped onto two different sets of files).

来自http://docs.djangoproject.com/en/dev/ref/settings/admin media prefix

其次,可能是您将文件系统上的目录与URL路径混淆了。尝试使用绝对URL,然后细化它们。


要添加的另一件事是,如果在子域/其他域上有单独的媒体服务器,则可以禁用静态媒体的cookie。节省一点处理和带宽。