WTForms - отображать значение свойства вместо поля HTML - PullRequest
5 голосов
/ 23 июня 2011

Я хочу повторно использовать шаблон, который у меня есть, с моей формой WTForms:

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

Однако на моей странице редактирования я хочу, чтобы поля ввода отображались как обычно (TextField, SelectField и т. Д.), В то время как на странице просмотра я хочу просто отобразить значение свойства, а не поле ввода со значением.

Редактировать страницу:

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

Просмотр страницы:

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

Я знаю, что могу получить доступ к значению поля через form.name.data, но есть ли способ сохранить тот же шаблон при вызове form.name() и каким-либо образом переключать, выводит ли это <input type="text"... или Current Name?

Ответы [ 3 ]

6 голосов
/ 23 июня 2011

Я создал пользовательский виджет:

from wtforms.fields import Field

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

Затем для своей страницы просмотра я добавил следующее:

form = MyForm(obj=myDataRow)
fields = [val for val in form._fields]
for fieldName in fields:
    fieldProp = getattr(form, fieldName)
    setattr(fieldProp, 'widget', PlainTextWidget())
4 голосов
/ 25 марта 2013

Ответ Сары, приведенный выше, привел меня к решению связанной проблемы: что если вы хотите, чтобы некоторые из ваших полей были доступны только для чтения? В этом случае вместо выполнения операции времени выполнения для объекта формы вы можете определить новый вариант ROTextField (например), который всегда отображается в чистом виде. Например:

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

Теперь определите ваше поле с атрибутами ReadOnly:

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

Размышления об этой проблеме помогли мне лучше понять, как работают WTForms. Оставьте это здесь на случай, если это может помочь кому-то еще разобраться со связанными проблемами.

1 голос
/ 09 июля 2015

На основании ответа Сары и кода, найденного в WTForms-Components Я использую следующее, чтобы быстро превратить все поля формы в доступные только для чтения и отключенные поля.

Предположим, у нас есть ProfileFormопределяется следующим образом:

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 ...

Определите следующий класс (на основе ReadOnlyWidgetProxy из WTForms-Components):

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)

Теперь наследуйте от ProfileForm следующим образом:

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