Python WTForms创建自定义小部件

Python WTForms创建自定义小部件,python,flask,wtforms,flask-wtforms,Python,Flask,Wtforms,Flask Wtforms,WTForms文档严重不足,它们甚至没有向您展示一个自定义小部件的示例,而该小部件不是从另一个小部件派生的 我正在尝试创建一个按钮类型,它不是html中的: submit = InlineButton(name='submit', type='submit', title='Save this page', textWithinSpan='Save') 这就是我正在尝试的: from flask.ext.wtf import Required, Length, EqualTo, Field,

WTForms文档严重不足,它们甚至没有向您展示一个自定义小部件的示例,而该小部件不是从另一个小部件派生的

我正在尝试创建一个按钮类型,它不是html中的

submit = InlineButton(name='submit', type='submit', title='Save this page', textWithinSpan='Save')
这就是我正在尝试的:

from flask.ext.wtf import Required, Length, EqualTo, Field, TextInput, html_params
from flask import Markup

class InlineButtonWidget(object):
  text = ''
  html_params = staticmethod(html_params)

  def __init__(self, input_type='submit', **kwargs):
    self.input_type = input_type

  def __call__(self, field, **kwargs):
    kwargs.setdefault('id', field.id)
    kwargs.setdefault('type', self.input_type)
    if 'value' not in kwargs:
        kwargs['value'] = field._value()
    return Markup('<button type="submit" %s><span>%s</span></button>' % (self.html_params(name=field.name, **kwargs), kwargs['textWithinSpan']))


class InlineButton(Field):
  widget = InlineButtonWidget()

  def __init__(self, label='', **kwargs):
    self.widget = InlineButtonWidget('submit', label)
  def __call__(self, **kwargs):
    return self.widget(self, **kwargs)
  def _value(self):
    if self.data:
        return u', '.join(self.data)
    else:
        return u''


class SignupForm(Form):
    name = TextField('Name', [Length(min=1, max=200)])
    submit = InlineButton(name='submit', type='submit', title='Save this page', textWithinSpan='Save')
需要从flask.ext.wtf导入,长度,等号,字段,文本输入,html参数
从flask导入标记
类InlineButtonWidget(对象):
文本=“”
html_参数=静态方法(html_参数)
定义初始化(自我,输入类型为提交,**kwargs):
self.input\u type=输入类型
定义调用(自身、字段、**kwargs):
kwargs.setdefault('id',field.id)
kwargs.setdefault('type',self.input_type)
如果“值”不以kwargs表示:
kwargs['value']=字段。_value()
返回标记(“%s%”(self.html_参数(name=field.name,**kwargs),kwargs['textWithinSpan']))
类InlineButton(字段):
widget=InlineButtonWidget()
定义初始化(self,label='',**kwargs):
self.widget=InlineButtonWidget('submit',label)
定义呼叫(自我,**kwargs):
返回self.widget(self,**kwargs)
def_值(自身):
如果是自助数据:
返回u','.join(self.data)
其他:
返回u“
班级报名表(表格):
name=TextField('name',[Length(最小值=1,最大值=200)])
submit=inline按钮(name='submit',type='submit',title='Save this page',textWithinSpan='Save')
我甚至不需要字段派生的对象。但当您仅单独使用小部件时,它不会显示

当你使用Field对象时,它会给你各种各样的无效参数错误

即使深入研究WTForms源代码,也很难理解为什么它不能将Kwargs从表单传递到小部件

---更新---

好的,在我提交问题后,我基本上找到了一个可行的解决方案:

class InlineButtonWidget(object):
    html_params = staticmethod(html_params)

    def __init__(self, input_type='submit', text=''):
        self.input_type = input_type
        self.text = text

    def __call__(self, field, **kwargs):
        kwargs.setdefault('id', field.id)
        kwargs.setdefault('type', self.input_type)
        if 'value' not in kwargs:
            kwargs['value'] = field._value()
        return Markup('<button type="submit" %s><span>%s</span></button>' % (self.html_params(name=field.name, **kwargs), field.text))


class InlineButton(Field):
  widget = InlineButtonWidget()

  def __init__(self, label=None, validators=None, text='Save', **kwargs):
    super(InlineButton, self).__init__(label, validators, **kwargs)
    self.text = text

  def _value(self):
        if self.data:
            return u''.join(self.data)
        else:
            return u''



class SignupForm(Form):
    name = TextField('Name', [Length(min=1, max=200)])
    submit = InlineButton('submit', text='Save', description='Save this')
类InlineButtonWidget(对象):
html_参数=静态方法(html_参数)
定义初始化(self,输入类型='submit',文本=''):
self.input\u type=输入类型
self.text=文本
定义调用(自身、字段、**kwargs):
kwargs.setdefault('id',field.id)
kwargs.setdefault('type',self.input_type)
如果“值”不以kwargs表示:
kwargs['value']=字段。_value()
返回标记(“%s%”(self.html_参数(name=field.name,**kwargs),field.text))
类InlineButton(字段):
widget=InlineButtonWidget()
def _uuinit uuuu(self,label=None,validators=None,text='Save',**kwargs):
超级(InlineButton,self)。\uuuu init\uuuuuuuuuu(标签、验证器、**kwargs)
self.text=文本
def_值(自身):
如果是自助数据:
返回u“”。加入(self.data)
其他:
返回u“
班级报名表(表格):
name=TextField('name',[Length(最小值=1,最大值=200)])
submit=inline按钮('submit',text='Save',description='Save this')

在更新下应答,但在字段派生类中需要此init

def __init__(self, label=None, validators=None, text='Save', **kwargs):
    super(InlineButton, self).__init__(label, validators, **kwargs)
    self.text = text

您可以利用字段上的有用属性,即此实例的“描述”和“标签”。这将产生一个更简单的设置:

from wtforms.widgets.core import HTMLString, html_params, escape

class InlineButtonWidget(object):
    def __call__(self, field, **kwargs):
        kwargs.setdefault('type', 'submit')
        # Allow passing title= or alternately use field.description
        title = kwargs.pop('title', field.description or '')
        params = html_params(title=title, **kwargs)

        html = '<button %s><span>%s</span></button>'
        return HTMLString(html % (params, escape(field.label.text)))
或者,要为其设置字段类型:

class InlineButtonField(BooleanField):
    widget = InlineButtonWidget()

class MyForm(Form):
    foo = InlineButtonField('Save', description='Save Me')
class InlineButtonField(BooleanField):
    widget = InlineButtonWidget()

class MyForm(Form):
    foo = InlineButtonField('Save', description='Save Me')