我有一个css文件 home_global.css ,其中包含以下内容:
body {
background-image: url("{% static 'citator/citator.jpg' %}");
}
此静态文件的加载方式为:
<link rel="stylesheet" href="{% static 'citator/home_global.css' %}" type="text/css">
但是,预期背景图片的网址无法解析,但会按字面解析。我想做的是在css文件中启用Django模板语法。
请注意,静态网址等均已正确设置,并且该问题不涉及此问题。
这个问题与我一个月前问过的另一个问题非常相似: How to use django template syntax in static files
但是,这里提供的答案是 javascript 所特有的,尤其要注意的是,“防止这种情况的基本问题是将上下文传递给render()函数中提到的模板在视图(或任何其他函数中,其行为方式相同,例如render_to-response())。”
如果我正确理解这一点,则此处没有相同的限制。此外,我随后从Django文档中了解到可以在各种文本文档中使用Django模板语法。因此,在我看来,在 this 情况下,我想在css文件中使用它,这应该是可能的。那么,我该怎么做?
答案 0 :(得分:3)
好了,一个半月后,我决定只浏览一下文档,看看我自己是否可以解决这个问题。我有一个可行的解决方案。这是这样做的方法。
步骤1:添加一些目录并在设置中设置一些新变量。
首先,我假设您已经具有用于静态文件的这样的目录结构:
/<app_name>/static/<app_name>
添加另一个名为“模板”的子目录。这是我们 we 制作模板的地方。这不是保存它们的地方。因此,您现在应该拥有这个:
/<app_name>/static/<app_name>/templates
在此目录中,添加您的CSS模板。这是我的示例,另存为“ test.css”:
{% load static %}
body {
background-image: url("{% static 'citator/citator.jpg %}");
}
现在将这些变量添加到设置中。请注意,我只有一个应用。如果您有更多的话,请找到一种更易于管理的方法:
APP_NAME = "<your app's name>"
STATIC_TEMPLATE_PATH = os.path.join(BASE_DIR, APP_NAME, "static", APP_NAME, "templates")
接下来,我们需要编写一个自定义命令,该命令将在这些模板上运行Django模板引擎。为此,请导航至:
/<app_name>/management/commands
如果没有这些目录,请进行创建。
然后,您需要制作一个文件,在以下目录中将其命名为“ render_static_templates.py”:
from django.core.management.base import BaseCommand
from django.template import engines
from <project_name>.settings import STATIC_TEMPLATE_PATH, APP_NAME
import glob
import os
def find_templates(stem: str):
"""
Custom template finder that just looks in
your new static templates directories for templates
"""
leaf = "*"
path = os.path.join(stem, leaf)
all_templates = glob.glob(path)
return all_templates
class Command(BaseCommand):
def handle(self, *args, **options):
# Get the file paths for all our new static templates:
all_templates = find_templates(STATIC_TEMPLATE_PATH)
# See docs: https://docs.djangoproject.com/en/2.1/topics/templates/
django_engine = engines['django']
for path in all_templates:
template = django_engine.get_template(path)
# Debug if you want. The URL should now be resolved in this print output.
print(template.render())
# Now we need to save the RENDERED template somewhere. I save it up one level from the templates folder, so that collectstatic can find it. You can put it elsewhere.
leaf = path.split("/")[-1]
save_path = os.path.join(APP_NAME, "static", APP_NAME, leaf)
# Debug
print(save_path)
with open(save_path, "w") as f:
f.write(template.render())
下一步是运行此新管理命令:
python manage.py render_static_templates
您现在应该可以在
中看到渲染的模板。/app/static/app
下次运行
python manage.py collectstatic
假设您已正确设置STATIC_ROOT和STATIC_URL,则将呈现的模板移动到应有的位置。就我而言:
/static/<app_name>
从那里开始,将使用您用于投放的内容投放RENDERED模板。 (我使用白噪声)。如果一切顺利,您应该在页面上看到背景图片!
可能的改进: -更好的目录结构。 -集成到“ collect_static”命令中。
答案 1 :(得分:3)
正如您正确指出的那样,Django模板可以用于任何文本文件,而不仅仅是HTML。但是,您需要确保它们是由模板引擎呈现的,并提供了特定的URL和视图。
这样,您可以期望对所有变量和标签进行插值,尤其是用settings.STATIC_URL替换“静态”。 但是,我不会坚持在CSS文件本身的URL之前加上“ / static /” ...这会很欺骗,因为您宁愿动态呈现文件。
在实践中:
project / urls.py
console.log(selectedExperience.from.split('/')[0])) // 04
console.log(months) // [ { value : 1, name: "one"}
{ value: 2, name: "two" }
{ value: 4, name: "four" } ]
console.log(months.find(month => month.value === selectedExperience.from.split('/')[0])); // undefined
该视图相当琐碎,并已内联到urls.py中。 请注意,我还指定了适当的模仿类型'text / css'。
在这里,我在URL前面添加了一个'css /'前缀,但这不是必需的,并且您的项目中不需要“ css”文件夹; 只要确保模板引擎可以找到“ home_global.css”即可;也就是说,将其放在所有已安装应用程序的/ template /子文件夹中, 甚至在项目中(如果已列出已安装的应用程序中的项目):
project / templates / home_global.css
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
...
path('css/home_global.css', TemplateView.as_view(
template_name='home_global.css',
content_type='text/css')
),
...
]
您可以通过使用浏览器导航到以下网址来立即检查结果:
{% load static %}
body {
background-image: url("{% static 'citator/citator.jpg' %}");
}
呈现文档如下:
http://127.0.0.1:8000/css/home_global.css
并根据需要将其包含在主模板中:
body {
background-image: url("/static/citator/citator.jpg");
}
是否需要渲染多个CSS文档,将文件名作为参数,然后对所有文档使用单个视图可能会比较方便。在这种情况下,为简单起见,我将选择基于函数的视图:
urls.py:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/home_global.css" type="text/css">
...
其中:
views.py
from django.urls import path
from . import views
urlpatterns = [
...
path('css/<str:filename>.css', views.css_renderer),
...
]
并在您的主模板中:
from django.shortcuts import render
def css_renderer(request, filename):
return render(request, filename + '.css', {}, content_type="text/css")
答案 2 :(得分:0)
切掉CSS标记的特定部分,然后使用style标记添加到HTML文件中。快速修复并为我工作。
main.css
...
#banner {
background-color: #e5474b;
color: #f2a3a5;
padding: 13em 0 11em 0;
background-color: #0c0c0c;
background-image: url("/images/banner.jpg"); <-- Remove this part and put under html
background-size: cover;
background-repeat: no-repeat;
background-position: 15% left;
text-align: right;
position: relative;
z-index: 9999;
}
...
index.html
<head>
...
<style>
#banner {
background-image: url("{% static 'images/banner.jpg' %}");
}
</style>
...
</head>