2011-06-23 17 views
5

que quieren volver a utilizar una plantilla que tengo con mi WTForms formulario:WTForms - valor de propiedad de presentación en lugar de campo HTML

<th>${form.name.label}</th> 
<td>${form.name()}</td> 
... 

Sin embargo, en mi página de edición, quiero que los campos de entrada para mostrar la forma habitual (TextField, SelectField, etc.), mientras que en mi página de vista, solo quiero mostrar el valor de la propiedad, no el campo de entrada con el valor.

página de edición:

<th>Name:</th> 
<td><input type="text" value="Current Name" name="name" id="name"/></td> 

Ver página:

<th>Name:</th> 
<td>Current Name</td> 

Sé que puedo acceder el valor de un campo a través de form.name.data, pero ¿hay alguna manera de poder mantener la misma plantilla con form.name() ser llamado y de alguna manera alternar si las salidas <input type="text"... o Current Name?

Respuesta

6

he creado un widget personalizado:

from wtforms.fields import Field 

class PlainTextWidget(object): 
    def __call__(self, field, **kwargs): 
     return field.data if field.data else '' 

Entonces, para mi página de vista, he añadido lo siguiente:

form = MyForm(obj=myDataRow) 
fields = [val for val in form._fields] 
for fieldName in fields: 
    fieldProp = getattr(form, fieldName) 
    setattr(fieldProp, 'widget', PlainTextWidget()) 
3

respuesta de Sarah anterior me llevó a la solución a un problema relacionado: ¿Qué si quieres que algunos de tus campos sean solo de lectura En ese caso, en lugar de realizar una cirugía en tiempo de ejecución en el objeto de formulario, podría definir una nueva variante ROTextField (por ejemplo), que siempre rinde al valor puro. Por ejemplo:

from wtforms.widgets import Input 
from wtforms.fields import StringField 

class TextOutput(Input): 
    def __call__(self, field, **kwargs): 
     return kwargs.get('value', field._value()) 

class ROTextField(StringField): 
    widget = TextOutput() 

Ahora definir el campo con atributos de sólo lectura:

class UserPrefs(Form): 
    name  = ROTextField('name', default='Jon') 
    # ... 

Pensando en este problema me ayudó a entender mejor cómo WTForms trabajo. Dejando esto aquí en caso de que esto pueda ayudar a otra persona a resolver problemas relacionados.

1

Basado en la respuesta y el código de Sarah encontrados en WTForms-Components Utilizo lo siguiente para convertir rápidamente todos los campos de un formulario en campos de solo lectura y deshabilitados.

Supongamos que tenemos un ProfileForm define como sigue:

class ProfileEditForm(Form): 
    title = StringField("Title", validators=[validators.required("Please enter your title.")]) 
    first_name = StringField("First Name", validators=[validators.required("Please enter your first name.")]) 
    middle_name = StringField("Middle Name") 
    last_name = StringField("Last Name", validators=[validators.required("Please enter your last name.")]) 
    organisation = StringField("Company Name", validators=[validators.required("Please enter your company name.")]) 
    organisation_website = StringField("Company Website") 
    # more fields ... 

definir la siguiente clase (basado en ReadOnlyWidgetProxy de WTForms-componentes):

class ReadOnlyAndDisabledWidgetProxy(object): 
    def __init__(self, widget): 
     self.widget = widget 

    def __getattr__(self, name): 
     return getattr(self.widget, name) 

    def __call__(self, field, **kwargs): 
     kwargs.setdefault('readonly', True) 
     kwargs.setdefault('disabled', True) 
     return self.widget(field, **kwargs) 

Ahora heredar de ProfileForm como sigue:

class ReadOnlyProfileForm(ProfileForm): 
    def __init__(self, *args, **kwargs): 
     super(ReadOnlyProfileForm, self).__init__(*args, **kwargs) 
     for field_name in self._fields: 
      field_property = getattr(self, field_name) 
      field_property.widget = ReadOnlyAndDisabledWidgetProxy(field_property.widget) 
Cuestiones relacionadas