Renderiza la macro Jinja2 sin molestar a lo que está en el rest de la plantilla

Trabajando en mi primer proyecto de Flask, me topé con la excepción jinja2.exceptions.UndefinedError al intentar renderizar una macro desde la plantilla Jinja2. Resultó que Jinja2 genera esta excepción cuando intenta analizar el rest de la plantilla que, de hecho, contiene referencia al objeto de solicitud global.

Aquí está la plantilla test.html que uso para el caso de prueba:

 {% macro test_macro() -%} Rendered from macro {%- endmacro %} {{ request.authorization }} 

Código del matraz # 1: representación de la plantilla (éxito):

 @app.route("/test") def test_view(): return render_template('test.html') 

Código del matraz # 2: renderizando la macro (falla):

 @app.route("/test") def test_view(): test_macro = get_template_attribute('test.html', 'test_macro') return test_macro() 

Si saca la {{ request.authorization }} de la plantilla, la segunda prueba se ejecutará con éxito.

Código del matraz # 3: usando la solución que encontré en el archivo de la lista de correo del matraz (éxito):

 @app.route("/test") def test_view(): t = app.jinja_env.get_template('test.html') mod = t.make_module({'request': request}) return mod.test_macro() 

Aunque ahora tengo un código de trabajo, me resulta incómodo no saber por qué falla el segundo enfoque. ¿Por qué Jinja2 incluso se preocupa por el rest de la plantilla cuando se requiere renderizar solo la macro?

Tienes toda la razón, ha sido causado en el lado Jinja. El método get_template_attribute() del Flask tiene este aspecto:

 return getattr(current_app.jinja_env.get_template(template_name).module, attribute) 

Por lo tanto, trata de recuperar el nombre de una plantilla, y luego, la llamada al module propiedades evalúa esta plantilla antes de que se genere la lista de propiedades. En su caso, la referencia a la request variable permaneció desconocida para el Jinja. Para más detalles, verifique las fonts environment.py de Jinja .