#django #django-widget #django-context #django-sekizai
#django #django-виджет #django-контекст #django-sekizai
Вопрос:
Я пишу пользовательское поле формы, в котором есть пользовательский виджет. Виджету нужны некоторые статические ресурсы. Его шаблон выглядит следующим образом:
{% 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 — на самом деле НЕ решает проблему. В конце концов, недостатки медиа-класса — вот почему 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 link в head и тег js script после body).
Если у кого-нибудь есть решение для использования addtoblock от sekizai в шаблоне, который не имеет доступа к объекту запроса, все равно добро пожаловать!
Обновление 2
Я могу использовать addtoblock и избежать ошибки контекста, переопределяющей метод 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
Однако ресурсы по-прежнему не отображаются…
Ответ №1:
Немного подумав и прочитав документы, я понимаю, что статические ресурсы для форм и виджетов выполняются django «из коробки»: