为 WTForms 表单编写验证器,比较来自两个字段的输入

Code a validator for a WTForms form which compares the inputs from two fields

feature_count 的输入小于 effective_rank 的输入时,我想要一个触发 ValidationException 的验证器。

我在该网站 (http://flask.pocoo.org/snippets/64/) 上找到了有关 wtforms 验证器的信息,但不知道如何将其应用到我的问题中。

你能告诉我它是怎么做的吗?

这是我的代码:

from flask_wtf import FlaskForm
from wtforms import SubmitField, IntegerField, ValidationError
from wtforms.validators import DataRequired, NumberRange, EqualTo,


class RequestDataForm(FlaskForm):
feature_count = IntegerField('Number of features', validators=[DataRequired(), NumberRange(min=1, max=50)])

effective_rank = IntegerField('Effective Rank', validators=[DataRequired()])

noise = IntegerField('Noise', validators=[DataRequired(), NumberRange(min=0, max=1)])

submit = SubmitField('Submit')

有一个叫做EqualToValidator可以用来比较两个字段是否相等。如果您希望 feature_counteffective_rank 相同,您只需添加:

feature_count = IntegerField('Number of features', validators=[DataRequired(), EqualTo('effective_rank'), NumberRange(min=1, max=50)])

但是,在您的特定情况下,您希望确保 LessThan 所以我拥有的最佳解决方案是复制并粘贴 EqualTo class 的代码,并根据您的需要重命名具体情况,更改比较并 re-utilise 将其作为自定义 class:

class EqualTo(object):  # --> Change to 'LessThan'
    """
    Compares the values of two fields.

    :param fieldname:
        The name of the other field to compare to.
    :param message:
        Error message to raise in case of a validation error. Can be
        interpolated with `%(other_label)s` and `%(other_name)s` to provide a
        more helpful error.
    """
    def __init__(self, fieldname, message=None):
        self.fieldname = fieldname
        self.message = message

    def __call__(self, form, field):
        try:
            other = form[self.fieldname]
        except KeyError:
            raise ValidationError(field.gettext("Invalid field name '%s'.") % self.fieldname)
        if field.data != other.data:  #  --> Change to >= from !=
            d = {
                'other_label': hasattr(other, 'label') and other.label.text or self.fieldname,
                'other_name': self.fieldname
            }
            message = self.message
            if message is None:
                message = field.gettext('Field must be equal to %(other_name)s.')

            raise ValidationError(message % d)

那么你可以使用:

feature_count = IntegerField('Number of features', validators=[DataRequired(), LessThan('effective_rank'), NumberRange(min=1, max=50)])