WTForms - 显示属性值而不是HTML字段

时间:2011-06-23 15:36:38

标签: python forms templates mako wtforms

我想重复使用我的WTForms表单模板:

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

但是,在我的编辑页面上,我希望输入字段显示为正常(TextFieldSelectField等),而在我的视图页面上,我只想显示值属性,而不是具有值的输入字段。

编辑页面:

<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"...或{ {1}}?

3 个答案:

答案 0 :(得分:6)

我创建了一个自定义小部件:

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

答案 1 :(得分:4)

Sarah上面的回答让我找到了相关问题的解决方案:如果你想让你的某些字段只读,该怎么办?在这种情况下,您可以定义一个新的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的工作原理。将此留在这里以防万一这可能有助于其他人解决相关问题。

答案 2 :(得分:1)

根据Sarah在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 ...

定义以下类(基于WTForms-Components的ReadOnlyWidgetProxy):

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)