【发布时间】:2021-01-19 12:18:09
【问题描述】:
我正在编写一个具有自定义小部件的自定义表单字段。小部件需要一些静态资产。它的模板如下所示:
{% 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 source 中发现提到 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
但是,资产仍未渲染...
【问题讨论】:
标签: django django-widget django-context django-sekizai