WTForms Могу ли я добавить атрибут-заполнитель при создании поля?

Я хочу добавить атрибут заполнителя в поле в WTForms. Как мне это сделать?

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

Приведенный выше код недействителен

Как я могу добавить атрибут-заполнитель со значением?


person Kit Ho    schedule 17.03.2012    source источник


Ответы (3)


Обновлено для WTForms 2.1

Теперь, начиная с WTForms 2.1 (декабрь 2015 г.), вы можете задавать ключевые слова для рендеринга, используя параметр render_kw= в конструкторе полей.

Таким образом, поле будет выглядеть так:

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

Обратите внимание, что это возможно; он начинает стирать грань между кодом и представлением; так что используйте его с умом!


(Старый ответ, все еще верный для версий старше WTForms 2.1)

placeholder не поддерживается в конструкторе Python в WTforms 2.0.x и ниже.

Однако вы можете легко сделать это в своем шаблоне:

{{ form.abc(placeholder="test") }}
person Crast    schedule 20.03.2012
comment
Вы правы, заполнитель должен быть стилем и не должен добавлять структурные элементы. - person Kit Ho; 23.03.2012
comment
Но что, если я использую макрос и вызываю его внутри цикла, который перебирает поля формы. Как я могу проверить внутри макроса, что поле имеет дополнительные атрибуты html? - person Marconi; 07.10.2012
comment
Заполнитель — это то же самое, что и метка. Следовательно, это содержание, а не стиль. Установка его в шаблоне делает невозможным использование общих шаблонов. - person Milimetric; 28.06.2013
comment
Аргумент ключевого слова description полей WTForms можно задавать при построении поля, он не проверяется, а просто копируется непосредственно в поле и, таким образом, может быть любым значением, а не только строкой, даже настраиваемым атрибутом. Если вы хотите перенести свои собственные метаданные, вы можете просто использовать это для переноса любых данных, которые вам могут понадобиться: TextField(..., description={'placeholder': foo', 'class': bar} (или даже пользовательский класс), затем используйте этот атрибут в своем шаблоне для любых специальных метаданных, которые вы хотите. - person Crast; 27.07.2013
comment
Чтобы добавить метку поля, вы можете написать: {{ form.abc(placeholder=form.abc.label.text) }} - person danbruegge; 10.06.2014
comment
Подводя итог, используйте: name = StringField('Name', description='John Smith'), а в шаблоне: {{ form.name(placeholder=form.name.description) }} - person Beau Barker; 02.02.2015
comment
Я против этого ответа, я не могу понять, как кто-то может думать, что заполнитель является настройкой отображения. Решение :D Plus на самом деле не работает для чего-то большего, чем жестко запрограммированная форма в вашем шаблоне. - person Drachenfels; 21.04.2015
comment
@Drachenfels, я согласен, в чем отличие от заполнителя и ярлыка. - person Nikolai Golub; 02.10.2015

Правильный ответ следующий:

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 %}
person Drachenfels    schedule 21.04.2015

Мое решение - использовать пользовательский виджет:

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 и определять ваши формы в коде форм, а не в шаблоне.

person Nikolai Golub    schedule 02.10.2015