我正在编写一个具有自定义小部件的自定义表单字段。小部件需要一些静态资产。它的模板如下所示:
{% load sekizai_tags static %}
<div id="myWidget"> ... </div>
{% addtoblock "css" %}
<link rel="stylesheet" href="{% static 'my_app/css/widget.css' %}">{% endaddtoblock %}
{% addtoblock "js" %}
<script src="{% static 'my_app/js/widget.js' %}"></script>{% endaddtoblock %}
但是,这不起作用。我得到:You must enable the 'sekizai.context_processors.sekizai' template context processor or use 'sekizai.context.SekizaiContext' to render your templates.
我猜这是因为表单(和小部件)无法访问请求对象?!有没有解决的办法?
我在 sekizai源中发现提到 SekizaiContext 为...
在没有可用请求的地方使用替代上下文而不是 RequestContext。
...但我无法弄清楚我会如何做到这一点。
请注意,我不想开始传递请求。这不是一个可接受的解决方案,因为我的自定义字段是可重用的;它应该以任何形式工作而无需进一步修改。
更新
实际上,在发布了我自己的问题的答案并且......再想一想之后,我意识到这个答案 - 使用 Media 类 - 并没有真正解决这个问题。毕竟,Media 类的缺点是首先需要 sekizai 的原因。
使用 Media 类意味着:
# widgets.py
class MyWidget(widgets.Widget):
template_name = "my_widget.html"
# other stuff
class Media:
css = {"all": "my_app/css/widget.css"}
js = ("my_app/js/widget.js")
然后,添加{{ form.media }}
到包含表单的模板。因此,发布此问题的初衷不会得到解决。即在小部件模板中使用addtoblock,以便可以按原样使用该字段,而无需对其他模板进行进一步修改。
此外,如果{{ form.media }}
使用了 html 标签,它将在表单之后立即呈现,除非我像这样包装它:{% addtoblock "css" %}{{ form.media }}{% endaddtoblock %}
. 然后将 css 和 js 都添加到同一个位置(而通常需要在头部添加 css 链接标签,在正文后添加 js 脚本标签)。
如果有人有在无法访问请求对象的模板中使用 sekizai 的 addtoblock 的解决方案,仍然欢迎!
更新 2
我能够使用 addtoblock 并避免覆盖我的 widgets.Widget 子类中的 get_context 方法的上下文错误,如下所示:
# widget.py
class MyWidget(widgets.Widget):
def get_context(self, name, value, attrs):
context = super().get_context(name, value, attrs)
sezikai_ctx_var = get_varname()
sekizai_ctx = SekizaiContext().flatten()
context.update({sezikai_ctx_var: sekizai_ctx[sezikai_ctx_var]})
return context
但是,资产仍然没有渲染......