web-dev-qa-db-fra.com

Python: WTForms Puis-je ajouter un attribut d'espace réservé lorsque j'initie un champ?

Je veux ajouter un attribut d'espace réservé sur le champ dans WTForms. Comment puis-je le faire?

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

Le code ci-dessus n'est pas valide

Comment puis-je ajouter un attribut d'espace réservé avec une valeur?

55
Kit Ho

mis à jour pour WTForms 2.1

Vous pouvez désormais, à partir de WTForms 2.1 (décembre 2015), définir des mots clés de rendu en utilisant le render_kw= paramètre au constructeur de champ.

Le champ ressemblerait donc à:

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

Notez que cela est possible; il commence à jeter un pont entre le code et la présentation; alors utilisez-le à bon escient!


(Ancienne réponse, toujours vraie pour les versions antérieures à WTForms 2.1)

placeholder n'est pas pris en charge dans le constructeur Python dans WTforms 2.0.x et versions antérieures).

Cependant, vous pouvez le faire facilement dans votre modèle:

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

La bonne réponse est la suivante:

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

Comme on peut le lire dans la documentation:

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

Puis dans votre modèle:

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

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

Où render_field est une macro définie dans 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 %}
7
Drachenfels

Ma solution est d'utiliser un widget personnalisé:

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

Ce n'est peut-être pas ellegant, mais cela permet d'utiliser Flask-Bootstrap et de définir vos formulaires dans le code des formulaires, pas dans le modèle

1
Nikolai Golub