将CSS类添加到WTForms SelectField中的选项

时间:2014-04-11 22:45:00

标签: python css flask wtforms flask-wtforms

任何人都可以告诉我如何将css类分配给选项值。 我想用小图像改变每个选项的背景,那么我怎么能用wtforms和css来做呢?

class RegisterForm(Form):
    username = TextField('username', [validators.Length(min=3, max=50), validators.Required()])
    img_url = SelectField('avatar', 
            choices=[('static/images/avatars/1.jpg', '1'), 
                ('static/images/avatars/2.jpg', '2'),
                ('static/images/avatars/3.jpg', '3'), 
                ('static/images/avatars/4.jpg', '4'),
                ('static/images/avatars/5.jpg', '5'), 
                ('static/images/avatars/6.jpg', '6'),
                ('static/images/avatars/7.jpg', '7'), 
                ('static/images/avatars/8.jpg', '8'),
                ('static/images/avatars/9.jpg', '9'), 
                ('static/images/avatars/10.jpg','10')])

2 个答案:

答案 0 :(得分:5)

如果你深入了解WTForms的内容,你会发现一个名为SelectField的小部件类

这是名为build the html string:

的方法
@classmethod
def render_option(cls, value, label, selected, **kwargs):
    options = dict(kwargs, value=value)
    if selected:
        options['selected'] = True
    return HTMLString('<option %s>%s</option>' % (html_params(**options), escape(text_type(label))))

这是调用上面定义的__call__函数的render_options方法。

def __call__(self, field, **kwargs):
    kwargs.setdefault('id', field.id)
    if self.multiple:
        kwargs['multiple'] = True
    html = ['<select %s>' % html_params(name=field.name, **kwargs)]
    for val, label, selected in field.iter_choices():
        html.append(self.render_option(val, label, selected))
    html.append('</select>')
    return HTMLString(''.join(html))

通过简单地实例化class,您将无法添加SelectField属性。执行此操作时,它会隐式创建Option个实例。在渲染时,仅使用render_optionsvalselected参数调用这些隐式实例的label方法。

您可以在事后访问隐式Option实例。这不是没有问题。如果你看一下@ Johnston的例子:

>>> i = 44
>>> form = F()
>>> for subchoice in form.a:
...     print subchoice(**{'data-id': i})
...     i += 1

他正是这样做的。但是你必须在渲染时为类提供属性。调用subchoice(**{'data-id': i})实际上吐出了预期的HTML。如果要将WTForms与模板引擎集成,则会出现相当大的问题。因为jinja之类的东西正在为你调用这些渲染函数。

如果您想要这种类型的行为,我建议编写您自己的SelectField实现,它允许您将属性传递给隐式Option实例。通过这种方式,模板引擎可以开展调用render的业务,您可以将表单的定义合并到forms.py文件中

答案 1 :(得分:3)

我只想告诉您,如果没有猴子修补或重写wtforms,这是可能的。库代码确实支持它,虽然不是很直接。我发现这一点是因为我遇到了和你一样的问题,我试图为WTForms写一个修复程序并自己提交了一个公关,后来发现你可以这样做(我花了几天时间试图解决这个问题) :

>>> from wtforms import SelectField, Form
>>> class F(Form):
...    a = SelectField(choices=[('a', 'Apple'), ('b', 'Banana')])
... 
>>> i = 44
>>> form = F()
>>> for subchoice in form.a:
...     print subchoice(**{'data-id': i})
...     i += 1
... 
<option data-id="44" value="a">Apple</option>
<option data-id="45" value="b">Banana</option>

请参阅此处的convo:
https://github.com/wtforms/wtforms/pull/81