2014-10-07 6 views
6

Esiste un modo per eliminare gli spazi bianchi circostanti da tutti i valori in WTForms senza aggiungere un filtro a ogni singolo campo?Spoglia automaticamente() tutti i valori in WTForms?

Attualmente sto passando filters=[strip_whitespace] con la funzione mostrata di seguito ai miei campi ma doverlo ripetere per ogni campo è abbastanza brutto.

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

Una soluzione che richiede la creazione di sottoclassi di Form sarebbe bene dato che sto già facendo nella mia applicazione.

risposta

8

si può fare in WTForms 2.x utilizzando il bind_field primitivo class Meta. Il paradigma class Meta è un modo per sovrascrivere i comportamenti di WTForm in contesti come campi di associazione/creazione di istanze, campi di rendering e altro.

Perché tutto sottoposto a override in class Meta definita in un form viene ereditata per le eventuali sottoclassi di forma, lo si può utilizzare per impostare una classe form di base con i tuoi comportamenti desiderati:

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 

Ora, solo ereditare MyBaseForm per tutti le tue forme e sei a posto.

+0

Penso che debba essere 'get' invece di' pop' o nessuno ma il primo Form non avrà filtri personalizzati. Inoltre, tale linea può essere semplificata un po ': 'filters = unbound_field.kwargs.get (' filters ', [])' – ThiefMaster

+0

@ThiefMaster ringrazia, corregge l'esempio di codice – Crast

+0

Questo non può essere fatto su 'FormField' dato che FormField non può accettare i filtri , quindi controlla prima di 'non issubclass (unbound_field.field_class, FormField)' – gdoumenc

1

Non sarei sorpreso se potessi farlo sottoclasse forma, ma la mia soluzione era solo creare campi personalizzati Stripped *. Penso che questo sia almeno meglio di passare i filtri ogni volta, perché è meno soggetto ad errori:

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 
+0

davvero una buona soluzione dato che richiede una sottoclasse di ogni singolo campo (WTForms ne ha molti) – ThiefMaster

0

Sfortunatamente, non ho abbastanza reputazione per commentare la prima risposta. Ma c'è il bug estremamente fastidioso nell'esempio nell'esempio: Quando esegui filters.append (smth), su ogni filtro di inizializzazione di ogni modulo aumenta di 1 elemento. Di conseguenza, il codice funziona sempre più lentamente fino al successivo riavvio

consideri Esempio:

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 

Quindi la correzione rapida è quello di verificare che questo non filtro nella lista:

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) 
Non