Flask WTForms 的自定义属性

Custom attributes for Flask WTForms

本文关键字:自定义属性 WTForms Flask      更新时间:2024-04-11

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

<form method="post" action="/">
    {{ form.hidden_tag() }}
    {{ form.name(placeholder="Name") }}
</form>

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

感谢您的帮助!

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") }}

将呈现placeholderng-model属性。

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

从 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)

直接在表单上使用它:

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="">
{{ form.username(placeholder='your name', size=20, **{'ng-model':'hello', 'class':'hello'}) }}

我认为更好