【问题标题】:manually fill in flask form field手动填写烧瓶表单字段
【发布时间】:2019-12-01 15:47:00
【问题描述】:

有人写了一个页面,让您填写表格并一次做一个事情,我正在处理另一个具有“批量”功能的页面,它需要更少的两个表单字段。

我一直在尝试回收他们的 Form 对象,而不是定义一个只是略有不同的新对象。

可以用文档中的示例来解释这一点: https://flask.palletsprojects.com/en/1.0.x/patterns/wtforms/

表单对象已创建:

from wtforms import Form, BooleanField, StringField, PasswordField, validators

class RegistrationForm(Form):
    username = StringField('Username', [validators.Length(min=4, max=25)])
    email = StringField('Email Address', [validators.Length(min=6, max=35)])
    password = PasswordField('New Password', [
        validators.DataRequired(),
        validators.EqualTo('confirm', message='Passwords must match')
    ])
    confirm = PasswordField('Repeat Password')
    accept_tos = BooleanField('I accept the TOS', [validators.DataRequired()])

有一个端点:

@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm(request.form)
    if request.method == 'POST' and form.validate():
        user = User(form.username.data, form.email.data,
                    form.password.data)
        db_session.add(user)
        flash('Thanks for registering')
        return redirect(url_for('login'))
    return render_template('register.html', form=form)

和 register.html(下面的一部分)

<form method=post>
  <dl>
    {{ render_field(form.username) }}
    {{ render_field(form.email) }}
    {{ render_field(form.password) }}
    {{ render_field(form.confirm) }}
    {{ render_field(form.accept_tos) }}
  </dl>
  <p><input type=submit value=Register>
</form>

现在假设您正在制作另一个不需要电子邮件字段但需要所有其他字段的页面。如果删除该行:

{{ render_field(form.email) }}

在html之外,页面会渲染好,但是当用户点击提交时,form.validate()将是False,所以它不会提交。

如何在 .py 文件中为表单对象提供一些内容,以便它忽略无法从浏览器发送的字段?

试过了

form.email = "field not needed here"

...在验证步骤之前,但它似乎没有工作

【问题讨论】:

    标签: python python-3.x flask flask-wtforms


    【解决方案1】:

    我猜你想要这样的东西:

    表单对象:

    from wtforms import Form, BooleanField, StringField, PasswordField, validators
    
    class CustomForm(Form):
        username = StringField('Username', [validators.Length(min=4, max=25)])
        password = PasswordField('New Password', [
            validators.DataRequired(),
            validators.EqualTo('confirm', message='Passwords must match')
        ])
        confirm = PasswordField('Repeat Password')
        accept_tos = BooleanField('I accept the TOS', [validators.DataRequired()])
    

    您的新端点,假设我们要创建一个没有电子邮件的用户:

    @app.route('/endpoint', methods=['GET', 'POST'])
    def register():
        form = CustomForm(request.form)
        if request.method == 'POST' and form.validate():
            user = UserWithoutEmail(form.username.data, form.password.data)
            db_session.add(user)
            flash('Thanks for registering')
            return redirect(url_for('login'))
        return render_template('register.html', form=form)
    

    和 register.html 显示除电子邮件以外的所有内容:

    <form method=post>
      <dl>
        {{ render_field(form.username) }}
        {{ render_field(form.password) }}
        {{ render_field(form.confirm) }}
        {{ render_field(form.accept_tos) }}
      </dl>
      <p><input type=submit value=Register>
    </form>
    

    【讨论】:

      【解决方案2】:

      我找到了改编自here的整洁解决方案

      class RegistrationForm2(RegistrationForm):
          def __init__(self, *args, **kwargs):
              super().__init__(*args, **kwargs)
              delattr(self, 'email')
      

      我喜欢它,因为它不需要再重复整个课程。不确定它是否比在 .py 表单中填充假值并避免定义新表单更优雅,但它可以工作。

      【讨论】:

        猜你喜欢
        • 2016-01-23
        • 1970-01-01
        • 2016-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-19
        • 1970-01-01
        • 2019-02-13
        相关资源
        最近更新 更多