使用for循环创建表单和生成字段

2024-09-30 18:33:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我想为过去10年中的每一年创建一个带有字段的表单。所以,对于2020-2011年,我希望,比如说,每年有一个整数字段,变量名为year_2020,year_2019,year_2018。。。如果他们也有合适的标签也不错,比如2020年、2019年

我可以通过每年单独写一些东西来做到这一点,但我认为使用for循环生成它们会更好、更有效(?)。这可能吗

我看到了this question关于使用for循环在模板中生成字段的内容,但我想知道如何在python表单类本身中生成字段(不确定该如何称呼它;请原谅我的无知)。我见过this question但我似乎无法让它发挥作用。我也不喜欢这个解决方案,因为它没有给字段提供描述性名称,比如year_2020

这是我到目前为止的代码;为任何错误道歉

python:

forms.py
    class YearForm(FlaskForm):
        year = IntegerField(validators=[NumberRange(min=0,max=100000,message='Please enter an integer above 0.'),
                            InputRequired(message='Please enter a value.')])
    
    class RentForm(FlaskForm):
        years = FieldList(FormField(YearForm), min_entries=10)

模板:

form.html
    for year in rentForm.years:
        <p>{{ year.label }}: {{ year(size=32) }}
            {% for error in year.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>

看起来我访问模板中的字段不正确。正确的方法是什么?如何为字段提供更多描述性标签和变量名

任何帮助都将不胜感激;谢谢

编辑:如果这可以更容易地用另一种语言完成,请让我知道。我刚开始学习Flask/Python,我也没有结婚


Tags: 模板表单messagefor标签minthisyear
2条回答

好的,我能够使用来自this question的信息制作一个令人满意的玩具示例

python:

class ImageForm(FlaskForm):
    frequency = SelectField(choices=[('monthly', 'Monthly'),('weekly', 'Weekly')])
    caption = StringField('Caption')
    credit = StringField('Credit')

class TestForm(FlaskForm):
    images = FieldList(FormField(ImageForm), min_entries=10)

模板:

<form action="" method="post">

    {{ testForm.hidden_tag() }}

    <table>
    {% for image in testForm.images %}
        <tr>
            <td> {{ image['frequency'] }} </td>
            <td> {{ image['caption'] }} </td>
            <td> {{ image['credit'] }} </td>
        </tr>
    {% endfor %}
    <table>
    
</form>

结果是: Rendered HTML (ignore all the tabs; I have a problem)

我想这应该很适合我的需要

PS:您可以访问单个字段,如下所示:

testForm.images[0]['frequency']

用于第一个下拉菜单

我也在做类似的事情。也许我的例子会有所帮助。我正在扩展表单,在您的例子中是RentForm.years,在我的Python烧瓶处理程序中,而不是在我的模板中。这是我的表格

class TemplateFormRow(FlaskForm):
    col = StringField(label='Column Name')
    data_type = SelectField(label='Data Type',
                            choices=[("boolean", "boolean"), ("datetime", "datetime"),
                                     ("integer", "integer"), ("decimal", "decimal"), ("string", "string")])
    sequence = HiddenField()
    delete = SubmitField(label='Delete')


class TemplateForm(FlaskForm):
    rows = FieldList(unbound_field=FormField(TemplateFormRow))
    add_row = SubmitField(label='Add Row', render_kw={'class': "btn btn-primary"})
    confirm = SubmitField(label='Save', render_kw={'class': "btn btn-primary"})
    btn_cancel = SubmitField(label='Cancel', render_kw={'formnovalidate': True, 'class': "btn btn-primary"})

注意,在我的例子中,我在父窗体上放置了一个按钮,允许用户添加另一行。如果您总是想要10行,那么处理它的方式会有所不同

下面是使用此表单的Python代码的一部分。append_条目行对您特别重要

如果request.method==“POST”:

if form.btn_cancel.data:
    return redirect(url_for('admin'))

if form.add_row.data:  # User pressed the add row button
    form.rows.append_entry()

下面是呈现模板的Python代码

return render_template(template_name_or_list='generic_entry_page.html', page_hdr='Template',
                       show_form=form, form_msg=msg)

最后,这里是我的模板处理这个的部分

                {% for element in show_form %}
                    {% if element is iterable %}  {# This is a vertical set of forms #}
                        <table>
                            <tr>
                                {% for field in element[0] %}
                                    {#                                      {% for field in element.rows[0] %}#}
                                    {% if field.type != 'HiddenField' and field.label.text != 'CSRF Token' %}
                                        <th>{{ field.label }}</th>
                                    {% else %}
                                        <th>{{ field }}</th>
                                    {% endif %}
                                {% endfor %}
                            </tr>
                            {% for row in element %}
                                <tr>
                                    {% for field in row %}
                                        <td>
                                            {% if field.type == 'SubmitField' %}
                                                <button {{ field }} {{ field.label.text }} </button>
                                            {% else %}
                                                {{ field }}
                                            {% endif %}
                                        </td>
                                    {% endfor %}
                                </tr>
                            {% endfor %}
                        </table>
                        <br>

生成的屏幕如下所示。。。 Hit add row button to add a row

这有用吗

相关问题 更多 >