Flask WTForms的自定义属性

kuy*_*nik 9 javascript python flask wtforms angularjs

我在Flask和AngularJS上开发网站.我需要使用AngularJS发送一个带AJAX的表单,但它需要输入字段的自定义属性.例如,我在Jinja2模板中有一个表单:

<form method="post" action="/">
    {{ form.hidden_tag() }}
    {{ form.name(placeholder="Name") }}
</form>
Run Code Online (Sandbox Code Playgroud)

那么如何从AngularJS添加一个属性让我的"名字"字段说"ng-model"?

谢谢你的帮助!

Mar*_*ers 13

Python标识符中不允许使用虚线,并且只有Python标识符可以keyword_argument=value在调用中用作对.

但是你有几种方法可以解决这个问题; 你可以通过在ng-一个前缀选项**kwargs映射,有Meta你使用Form类的翻译_,以-ng_属性,或使用自定义窗口小部件做同样的翻译.

传递**kwargs映射

随着**kwargs您可以在不Python的标识符传递参数,只要它们是字符串.用它来渲染表单域:

{{ form.name(placeholder="Name", **{'ng-model': 'NameModel') }}
Run Code Online (Sandbox Code Playgroud)

您可以render_kw在字段定义的映射中放入相同的信息:

class MyForm(Form):
    name = StringField(u'Full Name', render_kw={'ng-model': 'NameModel'})
Run Code Online (Sandbox Code Playgroud)

每当你渲染场地时它都会被使用; render_kw添加到渲染时传入的参数中,因此:

{{ form.name(placeholder="Name") }}
Run Code Online (Sandbox Code Playgroud)

会渲染两者placeholderng-model属性.

子类Meta并在您的表单中使用它

从WTForm 2.0开始,实际上要求Meta您附加到表单使用Meta.render_field()钩子呈现字段:

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)
Run Code Online (Sandbox Code Playgroud)

要么直接在表单上使用它:

class MyForm(Form):
    Meta = AngularJSMeta

    name = StringField(u'Full Name')
Run Code Online (Sandbox Code Playgroud)

或者是类的子Form类:

class BaseAngularJSForm(Form):
    Meta = AngularJSMeta
Run Code Online (Sandbox Code Playgroud)

并将其用作所有表单的基础:

class MyForm(BaseAngularJSForm):
    name = StringField(u'Full Name')
Run Code Online (Sandbox Code Playgroud)

现在您可以使用这是您的模板:

{{ form.name(placeholder="Name", ng_model='NameModel') }}
Run Code Online (Sandbox Code Playgroud)

子类小部件

您可以使用以下内容将您选择的小部件子类化:

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
Run Code Online (Sandbox Code Playgroud)

这会将任何以关键字参数开头ng_的关键字参数转换为开头ng-,确保可以添加正确的HTML属性.所述AngularJSMixin可与任何部件类的一起使用.

将其用作widget您字段的属性:

class MyForm(Form):
    name = StringField(u'Full Name', widget=AngularJSTextInput())
Run Code Online (Sandbox Code Playgroud)

再次,你可以使用ng_modelrenderig你的模板:

{{ form.name(placeholder="Name", ng_model='NameModel') }}
Run Code Online (Sandbox Code Playgroud)

在所有情况下,属性都将placeholder="Name" ng-model="NameModel"在呈现的HTML中添加:

<input id="name" name="name" ng-model="NameModel" placeholder="Name" type="text" value="">
Run Code Online (Sandbox Code Playgroud)


fly*_*gzl 11

{{ form.username(placeholder='your name', size=20, **{'ng-model':'hello', 'class':'hello'}) }}
Run Code Online (Sandbox Code Playgroud)

我觉得更好