В идентификаторах Python нельзя использовать дефисы, и только идентификаторы Python могут использоваться в качестве пар keyword_argument=value
в вызове.
Но у вас есть несколько способов обойти это здесь; вы можете передать параметры с префиксом ng-
в сопоставлении **kwargs
, указать класс Meta
, который вы используете для формы, для преобразования _
в -
для атрибутов ng_
или использовать настраиваемый виджет для выполнения того же преобразования.
Передайте карту ** kwargs
С **kwargs
вы можете передавать аргументы, которые не являются идентификаторами Python, если они являются строками. Используйте это для отображения полей формы:
{{ form.name(placeholder="Name", **{'ng-model': 'NameModel'}) }}
Вы можете поместить ту же информацию в отображение render_kw
в определении поля:
class MyForm(Form):
name = StringField(u'Full Name', render_kw={'ng-model': 'NameModel'})
и он будет использоваться каждый раз, когда вы визуализируете поле; render_kw
добавляется к любым аргументам, которые вы передаете при рендеринге, поэтому:
{{ form.name(placeholder="Name") }}
отобразит атрибуты placeholder
и ng-model
.
Подкласс Meta и используйте его в своей форме
Начиная с WTForm 2.0, действительно запрашивается Meta
класс, который вы прикрепляете к своей форме для отображения полей с помощью Meta.render_field()
hook:
import wtform.meta
class AngularJSMeta:
def render_field(self, field, render_kw):
ng_keys = [key for key in render_kw if key.startswith('ng_')]
for key in ng_keys:
render_kw['ng-' + key[3:]] = render_kw.pop(key)
# WTForm dynamically constructs a Meta class from all Meta's on the
# form MRO, so we can use super() here:
return super(AngularJSMeta, self).render_field(field, render_kw)
Либо используйте это прямо в вашей форме:
class MyForm(Form):
Meta = AngularJSMeta
name = StringField(u'Full Name')
или создать подкласс класса Form
:
class BaseAngularJSForm(Form):
Meta = AngularJSMeta
и используйте это как основу для всех ваших форм:
class MyForm(BaseAngularJSForm):
name = StringField(u'Full Name')
и теперь вы можете использовать этот шаблон с:
{{ form.name(placeholder="Name", ng_model='NameModel') }}
Виджеты подкласса
Вы можете создать подкласс виджета по вашему выбору с помощью:
class AngularJSMixin(object):
def __call__(self, field, **kwargs):
for key in list(kwargs):
if key.startswith('ng_'):
kwargs['ng-' + key[3:]] = kwargs.pop(key)
return super(AngularJSMixin, self).__call__(field, **kwargs)
class AngularJSTextInput(AngularJSMixin, TextInput):
pass
Это преобразует любой аргумент ключевого слова, начинающийся с ng_
, в аргумент ключевого слова, начинающийся с ng-
, обеспечивая возможность добавления правильных атрибутов HTML. AngularJSMixin
можно использовать с любым классом виджетов.
Используйте это как атрибут widget
в своем поле:
class MyForm(Form):
name = StringField(u'Full Name', widget=AngularJSTextInput())
и снова вы можете использовать ng_model
при рендеринге вашего шаблона:
{{ form.name(placeholder="Name", ng_model='NameModel') }}
Во всех случаях атрибуты будут добавлены как placeholder="Name" ng-model="NameModel"
в обработанный HTML:
<input id="name" name="name" ng-model="NameModel" placeholder="Name" type="text" value="">
person
Martijn Pieters
schedule
07.12.2013
**{...}
ключевого слова splash, поэтомуform.name(placeholder="Name", **{'ng-model': 'value'})
не сработает. Я думаю. - person Martijn Pieters   schedule 07.12.2013