Если вы заглянете глубоко в недра WTForms
, вы найдете класс виджетов с именем SelectField
.
это метод, называемый построением строки html:
@classmethod
def render_option(cls, value, label, selected, **kwargs):
options = dict(kwargs, value=value)
if selected:
options['selected'] = True
return HTMLString('<option %s>%s</option>' % (html_params(**options), escape(text_type(label))))
это метод __call__
, который вызывает функцию render_options
, определенную выше.
def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id)
if self.multiple:
kwargs['multiple'] = True
html = ['<select %s>' % html_params(name=field.name, **kwargs)]
for val, label, selected in field.iter_choices():
html.append(self.render_option(val, label, selected))
html.append('</select>')
return HTMLString(''.join(html))
Вы не сможете добавить атрибут class
, просто создав экземпляр SelectField
. Когда вы делаете это, он неявно создает экземпляры Option
. Во время рендеринга методы render_options
этих неявных экземпляров вызываются только с аргументами val
, selected
и label
.
Вы можете получить доступ к неявным экземплярам Option
постфактум. Это не без проблем. Если вы посмотрите на пример @Johnston:
>>> i = 44
>>> form = F()
>>> for subchoice in form.a:
... print subchoice(**{'data-id': i})
... i += 1
Он делает именно это. Но вы должны предоставить атрибуты классу во время рендеринга. Вызов subchoice(**{'data-id': i})
фактически выдает ожидаемое HTML
. Это создает серьезные проблемы, если вы интегрируете WTForms
с механизмом шаблонов. Потому что что-то вроде jinja
вызывает эти функции рендеринга для вас.
Если вам нужен такой тип поведения, я бы порекомендовал написать собственную реализацию SelectField
, которая позволит вам передавать атрибуты в неявные экземпляры Option
. Таким образом, механизм шаблонов может просто вызывать render
, а вы можете сохранять свои определения формы в своих forms.py
файлах.
person
nsfyn55
schedule
01.05.2014