如何使用Fask表单动态创建FieldLists

时间:2018-02-08 08:55:21

标签: python-2.7 flask flask-wtforms

我的用例如下:

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

以下是我的相同代码库:

var calc = (d1 - d2);
var hours = calc.Hours - (d1_timezone - (d2_timezone));

以下是我的home.html页面:

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)

以下是我的Companies.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>

但是我得到一个不可能理解的错误:'UnboundField'对象没有属性' call '。

请指导我。

1 个答案:

答案 0 :(得分:0)

简单的答案是不要真的担心它!

当您创建表单时,您正在设置业务和验证逻辑,我会欺骗一点并说:

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 %}

如果我们更改网址,则模板会显示正确的金额 - 例如,如果我们过高(/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根据需要添加表单元素 - 保存用户通过第一个“多少公司?”表单,而只是有一个“+”按钮,可以根据需要动态添加另一个公司元素,直到允许的最大值。