自动剥离()WTForms中的所有值?

时间:2014-10-07 08:52:43

标签: python wtforms

有没有办法从WTForms中的所有值中剥离周围的空格而不向每个字段添加过滤器?

目前我正在将filters=[strip_whitespace]以下所示的函数传递给我的字段,但是必须为每个字段重复此操作非常难看。

def strip_whitespace(s):
    if isinstance(s, basestring):
        s = s.strip()
    return s

需要对Form进行子类化的解决方案没问题,因为我已经在我的应用程序中这样做了。

3 个答案:

答案 0 :(得分:10)

您可以使用class Meta上的bind_field原语在WTForms 2.x中执行此操作。 class Meta范例是一种在上下文中覆盖WTForms行为的方法,例如绑定/实例化字段,渲染字段等。

因为在Form上定义的class Meta中被覆盖的任何内容都被继承到任何表单子类,您可以使用它来设置具有所需行为的基本表单类:

class MyBaseForm(Form):
    class Meta:
        def bind_field(self, form, unbound_field, options):
            filters = unbound_field.kwargs.get('filters', [])
            filters.append(my_strip_filter)
            return unbound_field.bind(form=form, filters=filters, **options)


def my_strip_filter(value):
    if value is not None and hasattr(value, 'strip'):
        return value.strip()
    return value

现在,只需为您的所有表单继承MyBaseForm,就可以了。

答案 1 :(得分:2)

不幸的是,我没有足够的声誉评论第一反应。 但是,在该示例中存在非常不愉快的错误: 当你执行filters.append(smth)然后在每个表单初始化过滤器增长1个元素。 因此,在重新启动代码之前,代码的工作速度会越来越慢

考虑例子:

   class MyBaseForm(Form):
        class Meta:
            def bind_field(self, form, unbound_field, options):
                filters = unbound_field.kwargs.get('filters', [])
                filters.append(my_strip_filter)
                return unbound_field.bind(form=form, filters=filters, **options)


    def my_strip_filter(value):
        if value is not None and hasattr(value, 'strip'):
            return value.strip()
        return value

    class MyCustomForm(MyBaseForm):
        some_field = StringField(filters=[lambda x: x])

    for i in range(100):
        MyCustomForm(MultiDict({'some_field': 'erer'}))

    print(len(MyCustomForm.some_field.kwargs['filters']))  # print: 101

因此,快速修复是检查此过滤器不在列表中:

class MyBaseForm(Form):
    class Meta:
        def bind_field(self, form, unbound_field, options):
            filters = unbound_field.kwargs.get('filters', [])
            if my_strip_filter not in filters:
                filters.append(my_strip_filter)
        return unbound_field.bind(form=form, filters=filters, **options)

答案 2 :(得分:1)

如果你能通过子类化表单来做到这一点我不会感到惊讶,但我的解决方案是创建自定义的Stripped *字段。我认为这至少比每次传递过滤器更好,因为它不易出错:

from wtforms import StringField, PasswordField


class Stripped(object):
    def process_formdata(self, valuelist):
        if valuelist:
            self.data = valuelist[0].strip()
        else:
            self.data = ''

class StrippedStringField(Stripped, StringField): pass
class StrippedPasswordField(Stripped, PasswordField): pass