【问题标题】:Automatically strip() all values in WTForms?自动剥离()WTForms中的所有值?
【发布时间】:2014-10-07 08:52:43
【问题描述】:

有没有什么方法可以去除 WTForms 中所有值的周围空白而不为每个字段添加过滤器?

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

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

需要子类化 Form 的解决方案会很好,因为我已经在我的应用程序中这样做了。

【问题讨论】:

    标签: python wtforms


    【解决方案1】:

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

    因为在表单上定义的 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 即可。

    【讨论】:

    • 我认为它必须是 get 而不是 pop 或者除第一个表单之外的任何表单都没有任何自定义过滤器。此外,该行可以简化一点:filters = unbound_field.kwargs.get('filters', [])
    • 这不能在FormField上完成,因为FormField不能带过滤器,所以在not issubclass(unbound_field.field_class, FormField)之前检查
    • 谢谢@gdoumenc,好点子。我认为为简单起见,我将保留代码示例......它说明了这一点,而不会过于深入细节。从理论上讲,您还可以将条形过滤器排除在非文本字段之外,依此类推。
    【解决方案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)
    

    【讨论】:

      【解决方案3】:

      如果您可以通过子类化表单来做到这一点,我不会感到惊讶,但我的解决方案是创建自定义的 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
      

      【讨论】:

      • 不是一个很好的解决方案,因为它需要对每个字段进行子类化(WTForms 有很多)
      猜你喜欢
      • 2016-05-15
      • 1970-01-01
      • 2010-09-10
      • 2013-03-17
      • 2011-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      相关资源
      最近更新 更多