WTForms 将小部件应用于 RadioField

WTForms applying widget to RadioField

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

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

创建:

  • 选项 1
  • 选项2
  • 选项3
  • 我想得到的是:

    选项 1 选项2 选项3

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

    在post提出这个问题之前,我尝试过自己解决问题。阅读此 post: 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 似乎有一个内置的小部件: class wtforms.widgets.Input(input_type=None) 这可能会通过不将无序列表标签应用于单选按钮来解决问题。

    我试过如下应用:

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

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

    我的问题是:

    TDLR:

    大家的3个问题都回答如下:

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

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



    一些解释以及我是如何想出来的:

    其实你是对的..

    我确定您可能使用了这样的验证器:

    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 Class(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 标签然后如果你不想使用任何一个(比方说 table)你必须使用另一个 class

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

    简单!与我们为验证器所做的相同,导入所需的 classes 并像这样更改所需的参数:

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

    在此示例中,我将 ul 或 li 更改为 TableWidget 在文档中阅读了相关内容 here

    它将显示为 table,如下所示:

    this Image shows gender as RadioField with also other fields

    稍后您可以通过添加 id 或 class 来设置 table 的样式。

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

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

    你也可以使用Flask-Bootstrap, 例如上面图片中的年龄(一个 IntegerField)在模板中看起来像这样:

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

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