WTForms将小部件应用于RadioField

时间:2020-01-28 11:45:53

标签: python html flask jinja2 wtforms

我需要在wtforms中创建一行单选按钮。所以:

buttons = RadioField(choices=[(0, 'Option1), (1, 'Option2'), (2, 'Option3')])

创建:

  • 选项1
  • Option2
  • Option3
  • 我想得到的是:

    选项1 选项2 选项3

    (由于某些原因,实际的单选按钮不在此处呈现) 意思是不是单排的按钮列表,我想要一行单选按钮。

    在发布问题之前,我已尝试自己解决问题。阅读这篇文章:How can WTForms RadioField generate html without <ul> and <li> tag?之后,我在这里阅读了有关小部件和按钮的信息: https://wtforms.readthedocs.io/en/stable/widgets.html#built-in-widgets 和这里: https://wtforms.readthedocs.io/en/stable/fields.html 似乎有一个内置的小部件: 类wtforms.widgets.Input(input_type = None)可能通过不将无序列表标签应用于单选按钮来解决此问题。

    我尝试将其应用如下:

    buttons = RadioField(widget=Input(input_type='radio'), choices=[(0, 'Option1'), (1, 'Option2'), (2, 'Option3')])
    

    但是我只得到错误: AttributeError:“ RadioField”对象没有属性“ _value”

    我的问题是:

    • “输入”小部件将我的按钮显示为一行而不是列表吗?
    • 如何正确应用?
    • 如果没有其他解决方案来显示我想要的按钮?

    1 个答案:

    答案 0 :(得分:3)

    TDLR:

    所有你的 3 Q. 回答如下:

    • 步骤:
    1. 选择正确的展示方式。
    2. 设置样式以使其内嵌。
    3. 在下面查看如何正确执行此操作。
    from wtforms import widgets
    
    
    Gender = RadioField('Gender', choices=[('M', 'Male'), ('F', 'Female')],
                            widget=widgets.TableWidget(with_table_tag=True) )
    
    • 导入小部件,以便您可以访问所有类并在小部件 arg 中使用所需的类。

    这里我使用了 TableWidget 类,您可以使用其他东西,也可以使用 table 然后在您的静态文件夹中添加一个 style.css 并设置您的表格样式,使其显示在一行中互联网上充斥着您如何为表格设计样式。例如检查这个



    一些解释以及我是如何发现的:

    其实你的方法是对的..

    看我确定你可能使用过这样的验证器:

    from wtforms import validators, ValidationError
    
    class ContactForm(FlaskForm):
        name = TextField("Student Name:", [
                         validators.Required("Plz enter your name.")])
    

    或者像这样:

    from wtforms.validators import DataRequired
    
    class RegistrationForm(FlaskForm):
        username = StringField('Username',
                               validators=[DataRequired(), Length(min=2, max=20)])
    

    你可能不明白它是如何工作的,想使用验证器导入它们...

    现在你可能会问这有什么关系?

    当您查看有关内置小部件的 link(您提供的)时:

    它说:

    class wtforms.widgets.ListWidget(html_tag='ul', prefix_label=True)
      # Renders a list of fields as a ul or ol list.
    

    并通过检查 widgets.core 模块准确地查看 ListWidget 类(source code

    class ListWidget(object):
    
       def __init__(self, html_tag='ul', prefix_label=True):
               assert html_tag in ('ol', 'ul')
               self.html_tag = html_tag
               self.prefix_label = prefix_label
    

    所以它检查(通过断言)选择 ul 或 li 标签然后如果你不想使用任何一个(比如表)你必须使用另一个类

    • 这意味着默认情况下我们使用 ul 或 li HTML 标签,我们该如何更改?

    简单!与我们对验证器所做的相同,导入所需的类并更改所需的参数,如下所示:

    from wtforms import widgets
    
    
    Gender = RadioField('Gender', choices=[('M', 'Male'), ('F', 'Female')],
                            widget=widgets.TableWidget(with_table_tag=True) )
    

    在此示例中,我将 ul 或 li 更改为 TableWidget,请参阅文档 here

    它将显示为这样的表格:

    this Image shows gender as RadioField with also other fields

    稍后您可以通过添加 id 或 class 并对其进行样式设置来设置表格的样式。

    这就是它在您的模板中的样子(我也在使用 Bootsrap 并计划单独设置标签和输入的样式):

    <div class="custom-control custom-radio custom-control-inline ">
            {{ form.Gender.label(class="custom-control-label") }}
             {{ form.Gender() }}
        </div>
    

    您也可以使用 Flask-Bootstrap, 例如上面图片中的年龄(整数字段)在模板中看起来像这样:

    {% import "bootstrap/wtf.html" as wtf %}
    .
    .
    .
    <div class="form-group">
            {{ wtf.form_field(form.Age, class='form-control', placeholder='Age') }}
        </div>
    

    这是在表单中显示所有字段,但有时您希望单独使用标签并单独设置其他字段的样式,以便我在 Gender RadioField 中执行的操作