尝试在动态WTForm字段中插入空白选项

时间:2017-10-18 22:11:41

标签: python flask wtforms flask-wtforms

我尝试在SOF here上找到的结果后,在现有的工作动态字段(客户)中添加空白选项,但是收到错误。

错误为ValueError: invalid literal for int() with base 10: ''.

如有必要,我可以提供完整的追溯。

以下是表单 - 动态字段是客户,您可以看到:

class FilterWorkorderForm(FlaskForm):
    id = IntegerField('id', validators=[Optional()])
    date = DateField('Date', validators=[Optional()])
    customer = SelectField('Customer', coerce=int, validators=[Optional()])
    customer_po = StringField('Customer PO', validators=[Optional()])
    requested_by = StringField('Requested By', validators=[Optional()])
    work_description = StringField('Work Description', validators=[Optional()])
    status = SelectField('Status', choices=[('Quote', 'Quote'), ('Pending', 'Pending'), ('WIP', 'WIP'), ('Complete', 'Complete'), ('TBI', 'TBI'), ('Invoiced', 'Invoiced'), ('VOID', 'VOID')])

以下是路线:

@app.route('/reports/filter_workorder', methods=['GET', 'POST'])
@login_required
def filter_workorder():
    results = None
    form = FilterWorkorderForm()
    form.customer.choices = [(cus.id, cus.company_name) for cus in Company.query.order_by('id')]
    ### LINE CAUSING ERROR ### form.customer.choices.insert(0, ("", "")) ### LINE CAUSING ERROR ###
    if request.method == 'POST':
        if form.validate_on_submit():
            try:
                customer_id = form.customer.data
                customer = Company.query.filter_by(id = customer_id).first_or_404()
                customer_name = customer.company_name
                filter_data = {'id' : form.id.data, 'date' : form.date.data, 'customer_po' : form.customer_po.data, 'customer' : customer_name, 
                'work_description' : form.work_description.data, 'status' : form.status.data}
                filter_data = {key: value for (key, value) in filter_data.items() if value}
                results = Workorder.query.filter_by(**filter_data).all()
            except Exception as e:
                db.session.rollback()
                flash(e)
        return render_template('filter_workorder.html', form = form, results = results)
    return render_template('filter_workorder.html', form = form)

1 个答案:

答案 0 :(得分:1)

问题是使用整数强制渲染表单,特别是客户字段。

根据WTForms's documentation on the Select widget

  

该字段必须提供一个iter_choices()方法,小部件将在渲染时调用该方法;此方法必须产生(value, label, selected)的元组。

如果你看the source code for this method

def iter_choices(self):
    for value, label in self.choices:
        yield (value, label, self.coerce(value) == self.data)

此方法中没有例外处理失败的强制。在您的情况下,self.coerce(value)会以int('')执行,这会导致您遇到的ValueError例外。

至少有两种解决方案:

  1. 删除coerce
  2. 使用0-1sentinel value来表示没有选择任何客户:

    form.customer.choices.insert(0, (0, ""))
    

    此值将通过强制执行,但您需要在表单处理后处理此值(以取消设置"客户"字段)。

相关问题