Comment rendre mon sélectionnez le champ avec WTForms?

J'ai un champ de sélection de qui a certains éléments délavé et des personnes handicapées, qui je tiens à rendre avec WTForms:

<select name="cg" id="cat" class="search_category">
<option value='' >{% trans %}All{% endtrans %}</option>  
<option value='' style='background-color:#dcdcc3' id='cat1'  disabled="disabled">-- {% trans %}VEHICLES{% endtrans %} --</option>
<option value='2'  {% if "2" == cg %} selected="selected" {% endif %} id='cat2' >{% trans %}Cars{% endtrans %}</option>
<option value='3' {% if "3" == cg %} selected="selected" {% endif %}   id='cat3' >{% trans %}Motorcycles{% endtrans %}</option>
<option value='4' {% if "4" == cg %} selected="selected" {% endif %}   id='cat4' >{% trans %}Accessories &amp; Parts{% endtrans %}</option>
...

J'ai une classe de formulaire qui fonctionne et j'ai commencé à mettre en œuvre pour localisées variable de catégorie mais je ne sais pas comment faire le widget(?) qui rend la délavé (background-color:#dcdcc3) et les handicapés attributs d'un élément option:

class AdForm(Form):
my_choices = [('1', _('VEHICLES')), ('2', _('Cars')), ('3', _('Bicycles'))]
name = TextField(_('Name'), [validators.Required(message=_('Name is required'))], widget=MyTextInput())
title = TextField(_('title'), [validators.Required(message=_('Subject is required'))], widget=MyTextInput())
text = TextAreaField(_('Text'),[validators.Required(message=_('Text is required'))], widget=MyTextArea())
phonenumber = TextField(_('Phone number'))
phoneview = BooleanField(_('Display phone number on site'))
price = TextField(_('Price'),[validators.Regexp('\d', message=_('This is not an integer number, please see the example and try again')),validators.Optional()] )
password = PasswordField(_('Password'),[validators.Optional()], widget=PasswordInput())
email = TextField(_('Email'), [validators.Required(message=_('Email is required')), validators.Email(message=_('Your email is invalid'))], widget=MyTextInput())
category = SelectField(choices = my_choices, default = '1')
def validate_name(form, field):
if len(field.data) > 50:
raise ValidationError(_('Name must be less than 50 characters'))
def validate_email(form, field):
if len(field.data) > 60:
raise ValidationError(_('Email must be less than 60 characters'))
def validate_price(form, field):
if len(field.data) > 8:
raise ValidationError(_('Price must be less than 9 integers'))

Je peux utiliser la variable de catégorie à partir de ci-dessus pour rendre une sélection des catégories. Je tiens également à activer l'affichage spécial ie désactivé éléments et fondu d'arrière-plan. Pouvez-vous me dire comment je dois faire?

Merci

Mise à jour

Lorsque vous essayez la solution à partir de la réponse d'ajouter les personnes handicapées de l'attribut, j'obtiens ce message d'erreur:

Trace:
Traceback (most recent call last):
File "/media/Lexar/montao/lib/webapp2/webapp2.py", line 545, in dispatch
return method(*args, **kwargs)
File "/media/Lexar/montao/montaoproject/i18n.py", line 438, in get
current_user=self.current_user,
File "/media/Lexar/montao/montaoproject/main.py", line 469, in render_jinja
self.response.out.write(template.render(data))
File "/media/Lexar/montao/montaoproject/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "/media/Lexar/montao/montaoproject/templates/insert_jinja.html", line 221, in top-level template code
{{ form.category|safe }}
ValueError: need more than 2 values to unpack

Le code que j'ai essayé était:

from wtforms.widgets import html_params
class SelectWithDisable(object):
"""
Renders a select field.
If `multiple` is True, then the `size` property should be specified on
rendering to make the field useful.
The field must provide an `iter_choices()` method which the widget will
call on rendering; this method must yield tuples of 
`(value, label, selected, disabled)`.
"""
def __init__(self, multiple=False):
self.multiple = multiple
def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id)
if self.multiple:
kwargs['multiple'] = 'multiple'
html = [u'<select %s>' % html_params(name=field.name, **kwargs)]
for val, label, selected, disabled in field.iter_choices():
html.append(self.render_option(val, label, selected, disabled))
html.append(u'</select>')
return HTMLString(u''.join(html))
@classmethod
def render_option(cls, value, label, selected, disabled):
options = {'value': value}
if selected:
options['selected'] = u'selected'
if disabled:
options['disabled'] = u'disabled'
return HTMLString(u'<option %s>%s</option>' % (html_params(**options), escape(unicode(label))))
class SelectFieldWithDisable(SelectField):
widget = SelectWithDisable()
def iter_choices(self):
for value, label, selected, disabled in self.choices:
yield (value, label, selected, disabled, self.coerce(value) == self.data)
class AdForm(Form):
my_choices = [('1', _('VEHICLES')), ('2', _('Cars')), ('3', _('Motorcycles'))]
nouser = HiddenField(_('No user'))
name = TextField(_('Name'), [validators.Required(message=_('Name is required'))], widget=MyTextInput())
title = TextField(_('Subject'), [validators.Required(message=_('Subject is required'))], widget=MyTextInput())
text = TextAreaField(_('Text'),[validators.Required(message=_('Text is required'))], widget=MyTextArea())
phonenumber = TextField(_('Phone number'))
phoneview = BooleanField(_('Display phone number on site'))
price = TextField(_('Price'),[validators.Regexp('\d', message=_('This is not an integer number, please see the example and try again')),validators.Optional()] )
password = PasswordField(_('Password'),validators=[RequiredIf('nouser', message=_('Password is required'))], widget=MyPasswordInput())
email = TextField(_('Email'), [validators.Required(message=_('Email is required')), validators.Email(message=_('Your email is invalid'))], widget=MyTextInput())
category = SelectFieldWithDisable(choices = my_choices)
def validate_name(form, field):
if len(field.data) > 50:
raise ValidationError(_('Name must be less than 50 characters'))
def validate_email(form, field):
if len(field.data) > 60:
raise ValidationError(_('Email must be less than 60 characters'))
def validate_price(form, field):
if len(field.data) > 8:
raise ValidationError(_('Price must be less than 9 integers'))

Je suppose que je dois définir le 'disabled' attribut quelque part, mais où?

Mise à jour 2

C'était plus compliqué que je ne le pensais. Il y avait aussi un la solution proposé sur le wtforms liste de diffusion mais je ne pouvais pas obtenir que le travail soit (certains banale erreur de syntaxe non valide et ne pas être en mesure d'importer ecscape de wtforms donc l'action que j'ai pris est de mettre à jour mon wtforms de l'hg référentiel si quelque chose d'important changement.

De la réponse ici je obtenir Need more than 2 values to unpack ou ValueError: too many values to unpack donc je canät semblent obtenir de droit. Dans mon modèle de ce que je suis en train de rendu est

{{ form.category }} 

et ma classe de formulaire est

class AdForm(Form):
my_choices = [('1', _('VEHICLES'), False, True), ('2', _('Cars'), False, False), ('3', _('Motorcycles'), False, False)]
...
category = SelectFieldWithDisable(choices = my_choices)

avec l'ajout de classes que j'ai obtenu à partir d'ici:

class SelectWithDisable(object):
"""
Renders a select field.
If `multiple` is True, then the `size` property should be specified on
rendering to make the field useful.
The field must provide an `iter_choices()` method which the widget will
call on rendering; this method must yield tuples of 
`(value, label, selected, disabled)`.
"""
def __init__(self, multiple=False):
self.multiple = multiple
def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id)
if self.multiple:
kwargs['multiple'] = 'multiple'
html = [u'<select %s>' % html_params(name=field.name, **kwargs)]
for val, label, selected, disabled in field.iter_choices():
html.append(self.render_option(val, label, selected, disabled))
html.append(u'</select>')
return HTMLString(u''.join(html))
@classmethod
def render_option(cls, value, label, selected, disabled):
options = {'value': value}
if selected:
options['selected'] = u'selected'
if disabled:
options['disabled'] = u'disabled'
return HTMLString(u'<option %s>%s</option>' % (html_params(**options), escape(unicode(label))))
class SelectFieldWithDisable(SelectField):
widget = SelectWithDisable()
def iter_choices(self):
for value, label, selected, disabled in self.choices:
yield (value, label, selected, disabled, self.coerce(value) == self.data)
Aussi ce moteur de template utilisez-vous pour la sortie de cette? Vous avez besoin d'écrire tous les et choisissez l'option de balises -- c'est l'un des points de l'utilisation de WTForms. Vous devriez être en mesure de faire: ad_form = AdForm() et puis dans votre sortie HTML, il suffit d'imprimer la valeur de "ad_form.catégorie" et "ad_form.nom de l'" et il va retourner le sous-jacent widget html de votre champ sélectionné.
(Ran out of room), mais voici un exemple d'utilisation de Jinja: {{ data.form.time(id="time", value=data.date.strftime("%H:%M"))}}. le temps est un Champ de texte dans la forme, cela renvoie <input type="text" id="time" name="time" value="[current time formatted as HH:MM]"> Vous pouvez également obtenir une étiquette pour votre domaine avec {{ data.form.time.label }} qui sera de retour <label for="time'>Time</label>
Le code ci-dessous est attendu recevrez un quatre élément d'un tuple: (valeur, nom, activée (True/False), désactivé (True/False))
Cet être vraiment vieux, je doute que je vais obtenir beaucoup d'aide, mais il serait bien de poster ce que vous avez fait qui a obtenu ce travail. Je suis coincé là où vous étiez.
Cheers, en fin de compte je n'ai trouver comment obtenir le code que vous étiez en train de travailler. Je vais essayer de poster un commentaire quand je suis à mon bureau à ce que j'avais besoin de changer.

OriginalL'auteur Niklas Rosencrantz | 2011-12-11