在网站的主要布局模板中使用 Flask-wtforms 的困难

Difficulties with having a Flask-wtforms in the main layout template of the website

我过去一直在使用 Flask 开发网站,python 和 bootstrap。我在我的网站上添加了页脚,我想在页脚中添加一个“联系我”表格。下面是我当前用于创建联系表单并显示此表单的代码。

class ContactForm(FlaskForm):
    email = StringField("", validators=[DataRequired(), Email()])
    content = TextAreaField("", validators=[DataRequired(), length(min=2, max=500)])

    submit = SubmitField("Submit")
<form method="POST" action="">
    <div class="form-group">
        {{ form.email.label(class="form-control-label") }}
        {% if form.email.errors %}
            {{ form.email(class="form-control form-control-lg is-invalid") }}
            <div class="invalid-feedback">
                {% for error in form.email.errors %}
                    <span>{{ error }}</span>
                {% endfor %}
            </div>
        {% else %}
            {{ form.email(class="form-control form-control-lg") }}
        {% endif %}
    </div>
    <div class="form-group">
        {{ form.content.label(class="form-control-label") }}
        {% if form.content.errors %}
            {{ form.content(class="form-control form-control-lg is-invalid") }}
            <div class="invalid-feedback">
                {% for error in form.content.errors %}
                    <span>{{ error }}</span>
                {% endfor %}
            </div>
        {% else %}
            {{ form.content(class="form-control form-control-lg") }}
        {% endif %}
    </div>
    <div class="form-group">
        {{ form.submit(class="btn btn-outline-info") }}
    </div>
</form>

我在我的“layout.html”文件中创建了这个页脚,该文件是所有其他 html 文档的基础文件,因此所有页面都将具有相同的页脚。

问题是我需要在应用程序的每个页面上创建此表单对象的实例,并处理每个页面上的 validate_on_submit。 (下面的示例代码)

@app.route("/random_page", methods=["GET", "POST"])
def random_page():
    form = ContactForm()

    if form.validate_on_submit():
        # code to send the email goes here

    return render_template("random_page")

我正在寻找一种更简单的方法来执行此操作,这样我就不需要在每个页面上重复代码,这样它就可以简单得多。我对烧瓶不是很有经验,非常感谢您的帮助。

使用 @app.context_processor 装饰器 documentation 将您的联系表单实例注入 所有 模板的模板上下文中。例如:

@app.context_processor
def inject():
    return dict(
        contact_form=ContactForm(),
    )

然后重写表单的 HTML 以使用 contact_form 模板变量,同时添加适当的操作路径。

<form method="POST" action="{{url_for('contact')}}">
    <div class="form-group">
        {{ contact_form.email.label(class="form-control-label") }}
        {% if contact_form.email.errors %}
            {{ contact_form.email(class="form-control form-control-lg is-invalid") }}
            <div class="invalid-feedback">
                {% for error in form.email.errors %}
                    <span>{{ error }}</span>
                {% endfor %}
            </div>
        {% else %}
            {{ contact_form.email(class="form-control form-control-lg") }}
        {% endif %}
    </div>
    <div class="form-group">
        {{ contact_form.content.label(class="form-control-label") }}
        {% if contact_form.content.errors %}
            {{ contact_form.content(class="form-control form-control-lg is-invalid") }}
            <div class="invalid-feedback">
                {% for error in contact_form.content.errors %}
                    <span>{{ error }}</span>
                {% endfor %}
            </div>
        {% else %}
            {{ contact_form.content(class="form-control form-control-lg") }}
        {% endif %}
    </div>
    <div class="form-group">
        {{ contact_form.submit(class="btn btn-outline-info") }}
    </div>
</form>  

然后添加一个路由来单独处理此表单的回传:

@app.route("/contact", methods=["POST"])
def contact():
    form = ContactForm()

    if form.validate_on_submit():
        # code to send the email goes here

    # blah blah