在WTForms的SelectField中为选项添加CSS类

4

请问有没有人可以告诉我如何给选项值分配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个回答

6

如果你深入研究WTForms,你会发现一个名为SelectField的小部件类。

这是生成HTML字符串的方法:

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

您无法通过简单实例化 SelectField 来添加 class 属性。这样做会隐式创建 Option 实例。在渲染时,这些隐式实例的 render_options 方法仅使用 valselectedlabel 参数调用。 您可以事后访问隐式的 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文件中。

4

我想让您知道,这是可以做到的,而不需要猴子补丁或重写wtforms。虽然不是非常直接,但库代码确实支持它。我发现这一点是因为我遇到了与您相同的问题,并尝试为WTForms编写修复并提交了PR,后来发现您只需执行以下操作即可解决此问题(我花了几天时间才找出这个方法):

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

点击此处查看对话记录:
https://github.com/wtforms/wtforms/pull/81


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接