Automatically strip () all values ​​in WTForms?

Is there a way to strip surrounding spaces from all values ​​in WTForms without adding a filter for each individual field?

I am currently passing filters=[strip_whitespace] function shown below to my fields, but repeating this for each field is pretty ugly.

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

A solution that requires subclassing Form would be fine, as I already do this in my application.

+6
source share
3 answers

You can do this in WTForms 2.x using the bind_field primitive on the class Meta . The meta paradox is a way to override the behavior of WTForms in contexts such as binding / creating fields, rendering fields, etc.

Since everything that is redefined in the class Meta defined in the Form is inherited to any subclasses of the form, you can use it to configure the base class of the form with the desired behavior:

 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 

Now just inherit MyBaseForm for all of your forms, and you're good to go.

+8
source

I would not be surprised if you can do this in the form of a subclass, but my solution was to simply create custom Stripped * fields. I think this is at least better than passing filters every time since it is less error prone:

 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 
+1
source

Unfortunately, I do not have enough reputation to comment on the first answer. But there is an extremely unpleasant mistake in this example: When you do filter.append (smth), in each form initialization filters the growth by 1 element. As a result, your code runs slower and slower until you restart it.

Consider an example:

  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 

Thus, a quick fix is ​​to verify that this filter is not in the list:

 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) 
0
source

Source: https://habr.com/ru/post/976344/


All Articles