我在Scenario(定义项目的特征)和Module(定义太阳能电池板的技术特性)之间有一对多的关系:几个项目可以使用相同的光伏模块。
我已经定义了一些模块,现在我希望能够在Scenario定义页面中选择一个模块。
我可以从我的数据库中提取数据,并可以使用下面的代码正确显示选择字段。
但是,在提交表单时,我收到一个SQL错误:InterfaceError: (sqlite3.InterfaceError) Error binding parameter 0 - probably unsupported type. [SQL: u'UPDATE scenario SET module_id=? WHERE scenario.id = ?'] [parameters: ([], 1)]
。看起来我的表单提交了空列表,我不知道该改变什么。
我在SO上发现了一些相关问题,但没有使用WTF Alchemy自动填充字段(我想保留)。
任何帮助将不胜感激!
macros.html
{% if field.type in ['ModelFieldList', 'QuerySelectField'] %}
<div class="control-group">
<select name="{{field.name}}" class="form-control">
{% for choice in field.choices %}
<option value="{{choice.id}}">{{choice.name}}</option>
{% endfor %}
</select>
</div>
{% else %}
...#Other fields
{% endif %}
models.py
class Scenario(db.Model):
id = db.Column(db.Integer,
primary_key=True,
autoincrement=True)
name = db.Column(db.String(140),
nullable=False,
info={'label': 'Name'})
module_id = db.Column(db.Integer,
db.ForeignKey(Module.id))
def __repr__(self):
return '{}'.format(self.name)
class Module(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(140), nullable=False,
info={'label': 'Name'},
unique=False)
scenario_list = db.relationship('Scenario',
backref=db.relationship('Scenario', backref='module', lazy='dynamic')
def __repr__(self):
return '{}'.format(self.name)
forms.py
ModelForm = model_form_factory(Form)
class ModuleForm(ModelForm):
class Meta:
model = Module
class ScenarioForm(ModelForm):
class Meta:
model = Scenario
module_id = ModelFieldList(SelectField(ModuleForm, coerce=int),
label= 'Module')
views.py
@app.route('/scenario/<int:id>/edit', methods=['POST', 'GET'])
def edit_scenario(id):
scenario = Scenario.query.get(id)
form = ScenarioForm()
if form.validate_on_submit():
form.populate_obj(scenario)
db.session.commit()
flash("{} successfully edited".format(scenario), "success")
form_action = url_for('scenario', id=id)
return redirect(form_action)
form = ScenarioForm(obj=scenario)
form.module_id.choices = db.session.query(Module.id, Module.name)
form_title = "Scenario"
form_action = url_for('edit_scenario', id=id)
return render_template('form.html',
form = form,
form_title = form_title,
form_action = form_action)
修改 在@dirn回答之后,我做了一些更改:它现在有效,只是我丢失了模块字段的标签。几乎就在那里!
forms.py
class ScenarioForm(ModelForm):
class Meta:
model = Scenario
module_id = SelectField(ModuleForm, choices = [(x.id, x.name) for x in db.session.query(Module).all()], coerce=int)
macros.html
{% if field.type in ['ModelFieldList', 'QuerySelectField', 'SelectField'] %}
<div class="control-group">
<select name="{{field.name}}" class="form-control">
{% for id, name in field.choices %}
<option value="{{id}}">{{name}}</option>
{% endfor %}
</select>
</div>
{% else %}
...
{% endif %}
修改
我在没有理解它的情况下从教程中复制粘贴语法,并且我使用SelectField()
初始化ModuleForm
函数。结果证明它没用,我需要把标签放在那里。
forms.py
class ScenarioForm(ModelForm):
class Meta:
model = Scenario
module_id = SelectField('Module', choices = [(x.id, x.name) for x in db.session.query(Module).all()], coerce=int)