Как использовать тег addtoblock 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 - НЕ решает проблему. В конце концов, именно из-за недостатков медиа-класса в первую очередь нужен сэкизай.

Использование класса 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 script после тела).

Если у кого-то есть решение для использования sekizai addtoblock в шаблоне, у которого нет доступа к объекту запроса, все равно добро пожаловать!

Обновление 2

Я могу использовать addtoblock и избежать ошибки контекста, переопределяющей метод get_context в моем подклассе widgets.Widget следующим образом:

# 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 прямо из коробки:

https://docs.djangoproject.com/en/3.1/topics/forms/media/

Другие вопросы по тегам