Python 标识符中不允许使用破折号,并且只有 Python 标识符可以用作调用中的 keyword_argument=value 对。
但是你有几个选项可以解决这个问题;您可以在**kwargs 映射中传递ng- 前缀选项,让您用于表单的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 class you attach to your form 实际上被要求使用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') }}
在所有情况下,属性将在呈现的 HTML 中添加为 placeholder="Name" ng-model="NameModel":
<input id="name" name="name" ng-model="NameModel" placeholder="Name" type="text" value="">