我想出了一种更适合你需求的方法。虽然这会给服务器带来更多的负载,但是适当的缓存可以帮助减轻大部分负担。下面我概述了一种方法,如果每个路径的CSS包含相同,那么应该可以工作。您需要创建一个单独的视图来包含所有这些文件,但是您实际上可以使用此方法优化您的CSS,使每个页面仅调用一次CSS。
import md5
class LoadCss(template.Node):
def __init__(self, tag_name, css):
self.css = css
self.tag_name = tag_name
def render(self, context):
request = context['request']
md5key = md5.new(request.path).hexdigest()
if md5key not in request.session:
request.session[md5key] = list()
request.session[md5key].append(self.css)
return '<!-- Require %s -->' % self.css
def do_load_css(parser, token):
tag_name, css = token.split_contents()
return LoadCss(tag_name, key)
register.tag('requires', do_load_css)
class IncludeCss(template.Node):
def __init__(self, tag_name):
self.tag_name = tag_name
def render(self, context):
request = context['request']
md5key = md5.new(request.path).hexdigest()
return '<link rel="stylesheet" href="/path/to/css/view/%s">' % md5key
def do_include_css(parser, token):
return IncludeCss(token)
register.tag('get_required_css', do_include_css)
views.py:
from django.conf import settings
from django.views.decorators.cache import cache_page
import os
@cache_page(60 * 15)
def css_view(request, md5key):
css_requires = request.session.get(md5key, list())
output = list()
for css in css_requires:
fname = os.path.join(settings.MEDIA_ROOT, 'css', css)
f = open(fname, 'r')
output.append(f.read())
HttpResponse(''.join(output), mimetype="text/css")
这样可以让您将CSS信息存储在上下文中,然后在会话中,并从视图中提供输出(使用缓存使其更快)。当然,这将增加一些服务器开销。
如果您需要根据更多内容而不仅仅是路径来变化CSS,则可以简单地修改
md5
行以满足您的需求。您可以访问整个请求对象和上下文,因此几乎所有内容都应该在其中。
注意:经过第二次审查,如果浏览器在会话填充之前获取CSS,则可能会导致竞争条件。我不认为Django是这样工作的,但我现在不想查看它。