在Flask-Security中的宏内使用url_for_security

时间:2017-03-13 21:35:05

标签: flask flask-security

我试图在几个不同的地方重新使用我的flask-security登录表单,所以我把它定义为这样的宏:

{% macro loginForm(inForm) %}
    <form class="form-signin" action="{{ url_for_security('login') }}" method="POST" name="loginForm">
        {{ inForm.hidden_tag() }}

        {{ renderFieldWithErrors(inForm.email, class="form-control top", placeholder="Login ID", required=True, autofocus=True) }}
        {{ renderFieldWithErrors(inForm.password, class="form-control bottom", placeholder="Password", required=True) }}

        <div class="checkbox">
            <label>
                {{ inForm.remember() }} Remember me
            </label>
        </div>
        <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>

        <p style="margin-top: 1em;"><a href="{{ url_for_security('forgot_password') }}">Trouble Logging In?</a></p>
    </form>
{% endmacro %}

不幸的是,url_for_security在此上下文中未定义。如果我将其更改为url_for,它可以正常工作,但之后它会说hidden_tag不存在。似乎宏没有定义与调用上下文相同的一组东西。这可以纠正吗?感谢。

1 个答案:

答案 0 :(得分:0)

默认情况下,宏与Jinja中的上下文一起导入。 From the documentation

  

默认情况下,包含的模板会在当前上下文中传递,而导入的模板则不会。这样做的原因是,与包括不同,导入是被缓存的。因为导入通常仅用作保存宏的模块。

和:

  

可以显式更改此行为:通过在导入/包含指令中添加上下文或不添加上下文,可以将当前上下文传递到模板并自动禁用缓存。

我自己遇到了这个问题,并通过更改宏在页面中的导入方式来解决了这个问题:

{% import "security/_components.html" as components with context %}

请记住,这将禁用缓存机制,因此根据宏在做什么,您可能会遇到性能下降的问题(尽管我没有足够的经验来扩展这一点)。

如果您想保留缓存,那么在其注释中提供的@stamaimer解决方案可以正常工作:在宏内使用url_for("security.login")而不是url_for_security("login")