WTForms 将小部件应用到 RadioField

Mr_*_*ppy 1 html python jinja2 flask wtforms

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

buttons = RadioField(choices=[(0, 'Option1), (1, 'Option2'), (2, 'Option3')])
Run Code Online (Sandbox Code Playgroud)

创建:

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

    选项1 选项2 选项3

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

    在发布问题之前,我已经尝试自己解决问题。阅读这篇文章后:How can WTForms RadioField generated 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')])
    
    Run Code Online (Sandbox Code Playgroud)

    但我只收到错误: AttributeError: 'RadioField' object has no attribute '_value'

    我的问题是:

    • 输入小部件会将我的按钮显示为一行而不是列表吗?
    • 我该如何正确应用它?
    • 如果没有,还有其他解决方案可以按照我想要的方式显示按钮吗?

    Shi*_*Sec 5

    TDLR:

    您所有的 3 个问题的答案如下:

    • 脚步:
    1. 选择正确的方式来展示它。
    2. 设计它的样式以使其对齐。
    3. 请查看下面的内容以了解如何正确执行此操作。
    from wtforms import widgets
    
    
    Gender = RadioField('Gender', choices=[('M', 'Male'), ('F', 'Female')],
                            widget=widgets.TableWidget(with_table_tag=True) )
    
    Run Code Online (Sandbox Code Playgroud)
    • 导入小部件,以便您可以访问所有类并在小部件参数中使用您想要的类。

    这里我使用了TableWidget类,你可以使用其他东西,但也可以使用表格。然后在静态文件夹中添加一个style.css表格并设置其样式。让它在一行中显示(互联网上充斥着这样的内容)如何设计你的桌子。



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

    你实际上是在正确的方式。

    我确信您使用过这样的验证器:

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

    或者也许像这样:

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

    如果您想使用验证器导入它们,您可能了解它是如何工作的。

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

    当您查看有关内置小部件的此链接(您提供的)时,它显示:

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

    并通过检查 widgets.core 模块中的 ListWidget 类(源代码)

    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
    
    Run Code Online (Sandbox Code Playgroud)

    因此,它检查(通过断言)选择或ul标签li,然后如果您不想使用其中一个(假设是表),则必须使用另一个类。

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

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

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

    ul在此示例中,我将或更改为 TableWidget,请在此处的li文档中阅读相关内容。

    它将显示为如下表格:

    该图像将性别显示为 RadioField 以及其他字段。

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

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

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

    您还可以使用Flask-Bootstrap,例如在上面的图片中,age(an IntegerField) 在模板中看起来像这样:

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

    这显示了表单中的所有字段,但有时您希望单独使用标签,而其余部分单独设置其样式,所以这就是我在 Gender RadioField 中所做的。

    • 顺便说一句:将来当您在网络开发时遇到此类问题或一般问题时。尝试查看检查(开发工具)并检查静态代码,我很早就知道我的问题是我有这些点,因为我知道 ul 的样子,但要仔细检查并查看 Flask 生成的内容,我看到了 HTML代码,实际上它是一个无序列表(ul)。这始终是一种调试的好方法,而不仅仅是在调试控制台上进行中继。 (2认同)