如何使用动态CSS渲染模板?

时间:2012-06-10 11:30:06

标签: django django-templates dynamic-css

我想在视图中创建一个动态CSS文件,然后渲染一个加载该CSS文件的模板。根据给视图的参数,每次调用视图时,CSS在某些位置可能具有不同的值。我该怎么做呢? (我应该补充一点,我没有在Python / Django中编写文件的经验。)

以下是我认为应该如何运作的简化示例:

# urls.py
urlpatterns = patterns('',
    (r'^myview/(?P<color>[0-9a-f]{6})/$', create_css_file),
)

# views.py
def create_css_file(request, color):
    raw = "@charset 'UTF-8';\n\n"
    raw += "body {\n"
    raw += "  color: #" + color + ";\n"
    raw += "}\n\n"

    f = open('mydynamic.css', 'r+')
    f.write(raw)

    return render_to_response('mytemplate.html', locals())

# mytemplate.html
{% extends "base.html" %}
{% block head %}
    <link rel="stylesheet" media="screen" href="{{ f.name }}" />
{% endblock %}

出于某种原因,这不起作用,尽管在生成的HTML页面的源代码中,看起来CSS文件正确加载。 f甚至可以正确到达模板,因为当我将<link>...行更改为

时,我可以看到其内容
<link rel="stylesheet" media="screen" href="{{ f }}" />

f代替f.name)。但HTML呈现时没有所需的颜色设置。任何人都可以告诉我为什么会这样吗?

我怀疑路径有问题,而且我用不同的路径玩弄了很多东西,但无济于事。

请不要建议我准备几个硬编码的CSS文件(正如我在类似问题的答案中找到的那样),因为会有几百种可能性。

3 个答案:

答案 0 :(得分:11)

如果你绝对需要,你可以动态创建一个css文件。

您可以在urls.py中创建一个条目。您可以将您想要的任何名称命名为外部世界的静态.css文件,但这些文件将动态创建。

(r'^(?P<color>[0-9a-f]{6})/dynamic.css$', dynamic_css)


def dynamic_css(request, color):
   """
   Create a css file based on a color criteria,
   or any other complicated calculations necessary
   """
   # do custom element positionting.
   return render_to_response('dynamic.css', {'color': color})


# dynamic.css    
body {
  background-color: {{ color }}
}

没有理由为此编写css文件。现在你可以加入

<link rel="styleshee" type="text/css" href="/purple/dymamic.css" />

在你的模板中。

如上所述,这不应仅用于改变一种颜色。这可以在您的模板中完成。如果你不得不做这样的事情,那么实现缓存可能是个好主意,因为每次请求页面时都必须动态生成.css,这可能是性能开销。这是一个更好的示例,显示您可以将urls.py条目命名为您想要的任何内容。并以html中的任何方式包含它们,即。如果您需要动态创建自定义javascript文件,可以在urls.py中创建一个条目,然后创建一个生成.js文件的视图。

答案 1 :(得分:3)

views.py:

def create_css_file(request, color):
    f = color
    return render_to_response('mytemplate.html', locals())

模板:

<body style = "color:{{f}}!important;">

不要动态创建css文件,这是不必要的。

答案 2 :(得分:1)

我选择了@ CatPlusPlus的建议:在视图中计算必要的值并向模板传递一个包含整个CSS的非常长的字符串(raw)。在模板中,我将其包括在内:

<style media="screen">{{ raw|safe }}</style>

感谢大家的努力!