验证 FlaskForm (Flask-WTForms) SelectField Populated with AJAX

Validating FlaskForm (Flask-WTForms) SelectField Populated with AJAX

我在提交包含由 AJAX 填充的 SelectField 的表单时遇到了一些问题。不要介意变量名前面的字母,它们是用来设置它们的顺序的,因为表格是自动生成的:

class CreateEmployeeForm(FlaskForm):
    code = StringField(
        'Employee Code', validators=[DataRequired(), Length(max=16)]
        )
    a__first_name = StringField(
        'First Name', validators=[DataRequired(), Length(max=128)]
        )
    aa__last_name = StringField(
        'Last Name', validators=[DataRequired(), Length(max=128)]
        )
    email = StringField(
        'Email', validators=[DataRequired(), Email(), Length(max=128)]
        )
    start_date = DateField(
        'Start Date', format='%Y-%m-%d', validators=[Optional()]
        )
    phone = StringField(
        'Telephone', validators=[DataRequired(), Length(min=10, max=16)]
        )
    type_id = SelectField(
        'Employee Type', choices=[], coerce=int, 
        validators=[not_blank, v_employee_type], 
        render_kw={'class': 'dropdown_pop', 'id': 'Employee_type:name'}
        )
    z__password = PasswordField(
        'Password', validators=[DataRequired(), Length(min=8)]
        )
    z__password2 = PasswordField(
        'Repeat Password', validators=[DataRequired(), EqualTo('z__password')]
        )
    zzzz__submit = SubmitField(
        'Create Employee', render_kw={'class': 'submit_btn'}
        )

    def validate_code(self, code):
        user = Employee.query.filter_by(code=code.data).first()
        if user is not None:
            raise ValidationError('This employee id is already taken.')

    def validate_email(self, email):
        user = Employee.query.filter_by(email=email.data).first()
        if user is not None:
            raise ValidationError('Please use a different email address.')

问题出在 type_id 上,通过 jQuery 调用 API.

从数据库中提取的选项在呈现时填充。

如果我尝试按原样提交表单,type_id 将无法验证,我将收到标准 Not a valid choice 错误。

我在其他地方读到,如果我为此字段设置自定义验证函数,它将覆盖常规的 FlaskForm 验证。 不幸的是,Flask-WTF 使用下划线来检测需要验证的内容,一旦我添加 validate_type_id 函数,应用程序就会崩溃。 我不认为该错误是相关的,因为它来自 FlaskForms 的构建方式。

我需要想办法。

所以我尝试创建一个外部验证函数并在表单内字段的验证器=[...] 中调用它。没用,仍然收到无效选择错误消息。

我正在尝试通过检查数据库中是否存在为该字段选择的选项来验证该字段。或者,有没有一种方法可以在不使用 validate_fieldName(...) 的情况下禁用该字段的验证?

我进退两难,我无法更改字段名称以排除下划线,因为这是用于在数据库中创建条目的方式。据我所知,我只能使用字母、数字和下划线作为 Python 中的变量名,所以从这个角度来看,我被搞砸了。

有什么想法吗?

您可以尝试 QuerySelectField 扩展程序来执行此操作。

https://wtforms.readthedocs.io/en/2.3.x/ext/#wtforms.ext.sqlalchemy.fields.QuerySelectField

那样Submitting a choice which is not in the query will result in a validation error.

此外,您可以查看此处提供的示例,了解如何通过 Ajax 填写 WTForm:

https://github.com/saltycrane/flask-jquery-ajax-example

它在从 Ajax 请求获得成功响应时更新 select 字段。