WTForms 我能在初始化字段时添加 placeholder 属性吗?

84

我想在WTForms字段中添加一个占位符属性。我该如何做?

abc = TextField('abc', validators=[Required(), Length(min=3, max=30)], placeholder="test")

上述代码不是有效的。

如何添加带有值的占位符属性?

4个回答

156

已更新至WTForms 2.1版本

从WTForms 2.1 (2015年12月) 开始,您可以通过在字段构造函数中使用render_kw=参数来设置渲染关键字。

因此,字段的形式如下:

abc = StringField('abc', [InputRequired()], render_kw={"placeholder": "test"})

请注意,尽管这是可能的,但这开始涉及到代码和呈现之间的界线,因此要明智使用它!


(旧答案,仍适用于 WTForms 2.1 以前的版本)

placeholder 在 WTforms 2.0.x 及以下版本中不支持 Python 构造函数。

但是,在您的模板中可以轻松实现此功能:

{{ form.abc(placeholder="test") }}

2
你是对的,占位符应该是样式,而不应该添加在结构元素中。 - TheOneTeam
17
占位符与标签是相同的东西。因此,它是内容而不是样式。将其设置在模板中会导致无法使用通用模板。 - Milimetric
12
WTForms字段的description关键字参数可以在字段构建时设置,它不会被检查,直接复制到字段上,因此可以是任何值,不仅仅是字符串,甚至是自定义属性。如果您想携带自己的元数据,只需使用这个关键字参数来传递任何您想要的数据: TextField(..., description={'placeholder': 'foo', 'class': 'bar'}(甚至是自定义类),然后在模板中使用此属性来获取任何特殊的元数据。 - Crast
3
为给字段添加标签,您可以写成:{{ form.abc(placeholder=form.abc.label.text) }} - danbruegge
2
我正在对这个答案进行负评,我无法理解有人怎么会认为占位符是一个显示设置。:D 此外,该解决方案对于任何超出模板中硬编码表单的内容都不起作用。 - Drachenfels
显示剩余3条评论

10

正确答案如下:

abc = TextField('abc', validators=[Required(), Length(min=3, max=30)], description="test")

正如文档中所述:

description – A description for the field, typically used for help text.

那么在你的模板中:

{% import 'forms.html' as forms %}

{% for field in form %}
    {{ forms.render_field(field) }}
{% endfor %}

其中 render_field 是在 forms.html 中定义的宏:

{% macro render_field(field) -%}

{% if field.type == 'CSRFTokenField' %}
    {{ field }}

    {% if field.errors %}
        <div class="warning">You have submitted an invalid CSRF token</div>
    {% endif %}
{% elif field.type == 'HiddenField' %}
    {{ field }}
{# any other special case you may need #}
{% else %}
    <div class="form-group">
        <label for="{{ field.label.field_id }}" class="col-sm-2 control-label">{{ field.label.text }}</label>
        <div class="col-sm-10">
            {{ field(placeholder=field.description) }}
            {% if field.errors %}
                <div class="alert alert-danger" role="alert">
                {% for err in field.errors %}
                    <p>{{ err|e }}</p>
                {% endfor %}
                </div>
            {% endif %}
        </div>
    </div>
{% endif %}

{%- endmacro %}

6
{{ form.username(class="input", placeholder="Please enter your username") }} 

2

我的解决方案是使用自定义小部件:

from flask.ext.wtf import Form
from wtforms import StringField, validators
from wtforms.widgets import Input


class CustomInput(Input):
    input_type = None

    def __init__(self, input_type=None, **kwargs):
        self.params = kwargs
        super(CustomInput, self).__init__(input_type=input_type)

    def __call__(self, field, **kwargs):
        for param, value in self.params.iteritems():
            kwargs.setdefault(param, value)
        return super(CustomInput, self).__call__(field, **kwargs)


class CustomTextInput(CustomInput):
    input_type = 'text'


class EditProfileForm(Form):
    first_name = StringField('First name',
                             validators=[validators.DataRequired()],
                             widget=CustomTextInput(placeholder='Enter first name'))

也许这样做并不优雅,但它可以使用Flask-Bootstrap,并在表单代码中定义表单,而不是在模板中定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接