【问题标题】:Add a CSS class to an option in a WTForms SelectField将 CSS 类添加到 WTForms SelectField 中的选项
【发布时间】:2014-05-26 06:28:47
【问题描述】:

谁能告诉我如何将 css 类分配给 choices 值。 我想用小图像改变每个选项的背景,那么我该如何使用 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')])

【问题讨论】:

    标签: python css flask wtforms flask-wtforms


    【解决方案1】:

    如果您深入了解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))))
    

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

    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 文件中

    【讨论】:

      【解决方案2】:

      我只是想让您知道,无需猴子修补或重写 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

      【讨论】:

        猜你喜欢
        • 2013-08-24
        • 1970-01-01
        • 2017-05-16
        • 2013-01-04
        • 1970-01-01
        • 2022-10-14
        • 2018-04-05
        • 1970-01-01
        • 2016-09-10
        相关资源
        最近更新 更多