【问题标题】:How to dynamically create FieldLists using Fask forms如何使用 Flask 表单动态创建字段列表
【发布时间】:2018-02-08 08:55:20
【问题描述】:

我的用例如下:

在主页/索引页面中,要求用户输入他迄今为止工作过的公司数量。根据他提供的号码,他将被重定向到另一种形式,他必须提供所有这些公司的名称和位置。

下面是我的代码库:

from flask import Flask,render_template,redirect,url_for
from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField,IntegerField,BooleanField,Form,FormField,FieldList,ValidationError
from wtforms.validators import InputRequired


app = Flask(__name__)
app.config['SECRET_KEY'] = 'MySecret!'

class CompanyDetailsForm(Form):
    company_name = StringField('Company name')
    location = StringField('Location')

class CompanyForm(FlaskForm):
    def __init__(self,entries):
        self.first_name = StringField('First name')
        self.companies = FieldList(FormField(CompanyDetailsForm),min_entries=entries)

class IndexForm(FlaskForm):
    no_of_companies = IntegerField('No of companies worked so far')

    def validate_no_of_companies(form,field):
        if field.data > 5:
            raise ValidationError("No of companies cannot be more than 5")

@app.route('/CompanyDetails/<number>',methods=["GET","POST"])
def company_details(number):
    form = CompanyForm(number)
    return render_template('Companies.html',form=form)

@app.route('/home',methods=["GET","POST"])
def home():
    form = IndexForm()
    if form.validate_on_submit():
        return redirect(url_for('company_details',number=form.no_of_companies.data))
    return render_template('home.html',form=form)

if __name__ == "__main__":
    app.run(debug=True)

下面是我的 home.html 页面:

<html>
<head>
    <title>Home form</title>
</head>
<body>
    <h1>
    Please enter below details 
    </h1>
    <form action="" method="POST">
    {{ form.csrf_token }}
    {{ form.no_of_companies.label }}
    {{ form.no_of_companies }}
    {% for error in form.no_of_companies.errors %}
    <ul>
        <li style="color:red">{{ error }}</li>
    </ul>
    {% endfor %}
    </form>
</body>
</html>

下面是我的 Companies.html 代码库:

<html>
<head>
    <title>Companies Form</title>
</head>
<body>
    <h1>
    Please enter below details 
    </h1>
    <form action="" method="POST">
    {{ form.csrf_token }}
    {{ form.first_name.label }}
    {{ form.first_name }}
    {% for l in form.companies() %}
    {{ l.form.company_name }}
    {{ l.form.location }}
    {% endfor %}
    </form>
</body>
</html>

但我遇到了一个无法理解的错误,例如:'UnboundField' object has no attribute 'call'。

请指导我。

【问题讨论】:

    标签: python-2.7 flask flask-wtforms


    【解决方案1】:

    简单的答案就是不用担心!

    当您创建表单时,您正在设置您的业务和验证逻辑,我会作弊并说:

    min_entries=5
    

    永远不可能有人填写六个条目,但他们有可能工作不到五个。我们可以处理空的。

    解决了这个逻辑——现在你只需要担心用户界面的大小,所以让我们稍微调整一下我们的路线,以便立即获得更好的数据:

    @app.route('/CompanyDetails/<int(min:1, max:5):number>', methods=["GET", "POST"])
    def company_details(number):
        form = CompanyForm(number)
        return render_template('Companies.html', form=form, companies=number)
    

    然后在我们的模板中我们可以这样做:

    {% for x in range(companies) %}
        <li>
        {{ form.companies[x].company_name.label }} {{ form.companies[x].company_name }}
        {{ form.companies[x].location.label }} {{ form.companies[x].location }}
        </li>
    {% endfor %}
    

    如果我们更改 URL,模板会呈现正确的数量 - 例如,如果我们太高 (/CompanyDetails/6),我们会收到 404 错误。

    如果我不那么懒惰,我可以设置min_entries=1, max_entries=5 并更手动地构建表单:

    {% for x in range(companies) %}
        <li>
            <label for="companies-{{x}}-company_name">
                Company name
            </label>
            <input 
                id="companies-{{x}}-company_name" 
                name="companies-{{x}}-company_name" 
            type="text" value="">
        </li>
        {# ETC #}
    {% endfor %}
    

    这可以被认为更明确,但最好的办法是让 JQuery 根据需要添加表单元素——节省用户通过第一个“有多少家公司?”表单,而只是有一个“+”按钮,它会根据需要动态添加另一个公司元素,直到允许的最大值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 2023-03-16
      • 1970-01-01
      • 2021-02-23
      • 2012-05-15
      • 2021-04-02
      • 2021-05-01
      相关资源
      最近更新 更多