如何将 Flask-WTForms 与 HTML 模板连接起来以获得联系表格?

How can I connect Flask-WTForms with the HTML-template for a Contact Form?

我是 Python 的新人,我正在尝试为我的个人博客建立联系页面。我对如何将联系路由与 HTML 模板连接起来感到很困惑。 这是我的 Python 代码:

class ContactForm(Form):

    name = TextField("Name", [validators.DataRequired("Message 1"), validators.Length(min=5, max=20)])
    email = TextField("Email", [validators.DataRequired("Message 2"), validators.Length(min=6,max=30)])
    message = TextField("Message",[validators.DataRequired("Message 3"), validators.Length(min=10, max=200)])
    phone = StringField("Phone", [validators.Optional(strip_whitespace=True)])
    submit = SubmitField("Send")
   
@app.route('/contact', methods= ["POST", "GET"])
def contact():

    form = ContactForm()


    if request.method == "POST":
        if form.validate() == False:
            flash("These fields are required")
            return render_template('contact.html', form=form)
        else:
            return "Form posted."

    elif request.method == "GET":
        return render_template('contact.html', form=form)


这是我的 HTML-联系页面模板:

<div class="container">
    <div class="row">
      <div class="col-lg-8 col-md-10 mx-auto">
        <p>Want to get in touch? Fill out the form below to send me a message and I will get back to you as soon as possible!</p>
        <form action="{{ url_for('contact') }}" name="sentMessage" id="contactForm" method=post>
          <div class="control-group">
            <div class="form-group floating-label-form-group controls">
              <label>Name</label>
              <input type="text" class="form-control" placeholder="Name" id="name" required data-validation-required-message="Please enter your name.">
              <p class="help-block text-danger"></p>
            </div>
          </div>
          <div class="control-group">
            <div class="form-group floating-label-form-group controls">
              <label>Email Address</label>
              <input type="email" class="form-control" placeholder="Email Address" id="email" required data-validation-required-message="Please enter your email address.">
              <p class="help-block text-danger"></p>
            </div>
          </div>
          <div class="control-group">
            <div class="form-group col-xs-12 floating-label-form-group controls">
              <label>Phone Number</label>
              <input type="tel" class="form-control" placeholder="Phone Number" id="phone" required data-validation-required-message="Please enter your phone number.">
              <p class="help-block text-danger"></p>
            </div>
          </div>
          <div class="control-group">
            <div class="form-group floating-label-form-group controls">
              <label>Message</label>
              <textarea rows="5" class="form-control" placeholder="Message" id="message" required data-validation-required-message="Please enter a message."></textarea>
              <p class="help-block text-danger"></p>
            </div>
          </div>
          <br>
          <div id="success"></div>
        <button type="submit" class="btn btn-primary" id="sendMessageButton">Send</button>
      </form>
       </div>
      </div>
  </div>

将 HTML 模板(名称、电子邮件、消息、phone)中的表单与 Python 路由连接起来的最佳方式是什么,以便一次所有字段都已填写并单击“发送”按钮”,出现消息“已发布表单。”?我阅读了有关 WTF 表单的 Flask 文档,但我仍然不确定它是如何工作的。 非常感谢您的各种建议。

我已经更新了你的联系方式:

class ContactForm(FlaskForm):

    name = TextField("Name", [validators.DataRequired("Message 1"), validators.Length(min=5, max=20)])
    email = TextField("Email", [validators.DataRequired("Message 2"), validators.Length(min=6,max=30)])
    message = TextField("Message",[validators.DataRequired("Message 3"), validators.Length(min=10, max=200)])
    phone = StringField("Phone", [validators.Optional(strip_whitespace=True)])
    submit = SubmitField("Send")

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

    form = ContactForm()
    if form.validate_on_submit():
        name = form.name.data
        email = form.email.data
        message = form.message.data
        phone = form.phone.data
        return "Form posted. name: {}, email:{}, message:{}, phone:{}".format(name, email, message, phone)
    return render_template('contact.html', form=form)

在这里,我为您简化了这段代码,现在您无需检查它是 post 还是获取请求

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

    form = ContactForm()
    if form.validate_on_submit():
        name = form.name.data
        email = form.email.data
        message = form.message.data
        phone = form.phone.data
        return "Form posted. name: {}, email:{}, message:{}, phone:{}".format(name, email, message, phone)
    return render_template('contact.html', form=form)
如果表单通过了所有验证器,

form.validate_on_submit 将评估为 true,如果它没有通过验证器,或者根本没有表单(如在 get 请求中),这将评估为 false ,并将呈现 contact.html

return 功能仅用于演示正在接收表单以及您如何访问数据。 而不是简单地 returning/printing 你可以对数据做任何你想做的事,将它们发送到你的电子邮件,post 它们在你的博客上,等等...

return "Form posted. name: {}, email:{}, message:{}, phone:{}".format(name, email, message, phone)

这是你的 contact.html:

  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-md-10 mx-auto">
        <p>Want to get in touch? Fill out the form below to send me a message and I will get back to you as soon as possible!</p>
        <form action="" name="sentMessage" id="contactForm" method="POST">
          {{ form.hidden_tag() }}

          <div class="form-group">
            {{ form.name.label() }}
            {{ form.name() }}
          </div>
          <div class="form-group">
            {{ form.email.label() }}
            {{ form.email() }}
          </div>
          <div class="form-group">
            {{ form.phone.label() }}
            {{ form.phone() }}
          </div>
          <div class="form-group">
            {{ form.message.label()}}
            {{ form.message()}}
          </div>
          <br>
          <div id="success"></div>
          <div class="form-group">
            {{form.submit()}}
          </div>
      </form>
       </div>
      </div>
  </div>

我已经使用 Jinja 模板传递了参数 {{form.name.label}} 和 {{form.name}}, read about Jinja here

form.name.label 将显示您传递给该字段的值(如“姓名”和“消息”) form.name 将显示输入字段,与 form.email、form.phone 等相同...

如果未通过验证,您还希望在每个字段下方打印出错误, 说如果有人没有达到要求的长度,它将打印如下内容:

*字段长度必须在 10 到 200 个字符之间。

*电子邮件不正确

方法是检查每个表单字段中是否有错误,如果有它们将存储在 form.name.errors 中,如果有则必须迭代它们每个字段有不止一个错误(只有通过不止一次验证器检查才会发生这种情况)

这里是 contact.html,打印有误:

  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-md-10 mx-auto">
        <p>Want to get in touch? Fill out the form below to send me a message and I will get back to you as soon as possible!</p>
        <form action="" name="sentMessage" id="contactForm" method="POST">
          {{ form.hidden_tag() }}

          <div class="form-group">
            {{ form.name.label() }}
            {% if form.name.errors %}
                {{ form.name() }}
                <div class="invalid-feedback">
                {% for error in form.name.errors %}
                  <span>* {{ error }}</span>
                {% endfor %}
                </div>
            {%else%}
                {{ form.name() }}
            {% endif %}

          </div>
          <div class="form-group">
            {{ form.email.label() }}
            {% if form.email.errors %}
                {{ form.email() }}
                <div class="invalid-feedback">
                {% for error in form.email.errors %}
                  <span>* {{ error }}</span>
                {% endfor %}
                </div>
            {%else%}
                {{ form.email() }}
            {% endif %}
          </div>
          <div class="form-group">
            {{ form.phone.label() }}
            {% if form.phone.errors %}
                {{ form.phone() }}
                <div class="invalid-feedback">
                {% for error in form.phone.errors %}
                  <span>* {{ error }}</span>
                {% endfor %}
                </div>
            {%else%}
                {{ form.phone() }}
            {% endif %}

          </div>
          <div class="form-group">
            {{ form.message.label()}}
            {% if form.message.errors %}
                {{ form.message() }}
                <div class="invalid-feedback">
                {% for error in form.message.errors %}
                  <span>* {{ error }}</span>
                {% endfor %}
                </div>
            {%else%}
                {{ form.message()}}
            {% endif %}
          </div>
          <br>
          <div id="success"></div>
          <div class="form-group">
            {{form.submit()}}
          </div>
      </form>
       </div>
      </div>
  </div>

注意 jinja 使用 {% %} 作为语句,使用 {{ }} 作为变量,语句也需要使用 {% endif %} 和 {% endfor %}

此外,我建议您取消名称的最小长度要求,只保留最大长度

我还建议您对电子邮件字段使用 validators.Email(),这将确保用户将插入真实的电子邮件。

希望对您有所帮助,祝您有愉快的一天。