Django. Если мой тег шаблона принимает контекст и контекст изменяется, доступны ли его новые переменные в остальной части моей страницы?

У меня есть тег шаблона, который принимает контекст. В нем я добавляю переменную в свой контекст. Кажется, эта переменная правильно печатается в шаблоне, который включает мой тег шаблона (назовем его «рабочий стол»). Но в шаблоне, который включает ЭТОТ шаблон, у него больше нет переменной.

Я гуглил документы django, потому что мне любопытно, что здесь происходит. Доступна ли переменная контекста моего тега шаблона только в шаблоне, который включает ее, а не за ее пределами, как кажется?


person MiaZ    schedule 03.12.2015    source источник
comment
Насколько мне известно, контекст рендеринга тега шаблона применяется только к шаблону, который он рендерит. Он не перезапишет контекстную переменную, используемую в других местах шаблона. Что вы пытаетесь достичь?   -  person Brandon    schedule 04.12.2015
comment
Мне просто было любопытно обнаружить, что моя переменная печаталась в шаблоне, содержащем включение в мой тег шаблона. Я ожидал, что он будет ограничен, как вы говорите, шаблоном, который он отображает. Но нет, хотелось подняться на один шаг вверх, но не дальше.   -  person MiaZ    schedule 04.12.2015


Ответы (1)


В библиотеке Django, django.template.base, у вас есть функция parse_bits. В этой функции контекст представления копируется в новую переменную.

if takes_context:
    if params[0] == 'context':
        params = params[1:]
    else:
        raise TemplateSyntaxError(
            "'%s' is decorated with takes_context=True so it must "
            "have a first argument of 'context'" % name)

А в функции рендеринга класса InclusionNode создается новый объект контекста для рендеринга шаблона тега шаблона:

class InclusionNode(TagHelperNode):

            def render(self, context):
                """
                Renders the specified template and context. Caches the
                template object in render_context to avoid reparsing and
                loading when used in a for loop.
                """
                resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
                _dict = func(*resolved_args, **resolved_kwargs)

                t = context.render_context.get(self)
                if t is None:
                    if isinstance(file_name, Template):
                        t = file_name
                    elif isinstance(getattr(file_name, 'template', None), Template):
                        t = file_name.template
                    elif not isinstance(file_name, six.string_types) and is_iterable(file_name):
                        t = context.template.engine.select_template(file_name)
                    else:
                        t = context.template.engine.get_template(file_name)
                    context.render_context[self] = t
                new_context = context.new(_dict)
                # Copy across the CSRF token, if present, because
                # inclusion tags are often used for forms, and we need
                # instructions for using CSRF protection to be as simple
                # as possible.
                csrf_token = context.get('csrf_token', None)
                if csrf_token is not None:
                    new_context['csrf_token'] = csrf_token
                return t.render(new_context)

Поэтому он не должен распространять контекст тега шаблона на вызывающий шаблон.

person Cedric Roy    schedule 04.12.2015
comment
Спасибо, Седрик, но, согласно моей живой демонстрации, контекст тега шаблона по-прежнему доступен в шаблоне, который включает тег шаблона (и только ниже включения, а не на уровне выше в серии включений) x_x - person MiaZ; 04.12.2015