我有一个奇怪的问题,烧瓶,烧瓶重量和烧瓶sqlalchemy。
我有以下表格:
class CompEditForm(Form):
name = StringField('Company name', validators = [Required()])
desc = TextAreaField('Description')
address = StringField('Adress', validators = [Required()])
...
sectors = SelectMultipleField(u'Sectors', coerce=int)
submit = SubmitField(u'Save changes')
当我写一个烧瓶视图来编辑公司时:
def edit_company(id):
comp = Company.query.get_or_404(id)
form = CompEditForm(request.form,comp)
上面的代码预先填写了表格,其中包含名称,描述等所有字段。由于公司可以在不同的行业中运营,因此我建议使用多对多关系。我尝试使用以下内容填充表单的SelectMultipleFiled:
form.sectors.choices = [(g.id, g.name_srb) for g in Sector.query.order_by('name')]
到目前为止一直很好,表单中填充了各个扇区并且效果很好。这与创建新公司的表单相同。当我希望用现有的部门预先填充编辑表格时,问题出现了:
form.sectors.data = [c.id for c in comp.sectors.all()]
它使用正确的扇区填充表单,即在渲染时选择它们,但是当我提交表单时,它们不会改变并匹配用户的输入。它们保持不变:
if form.validate_on_submit():
print form.sectors.data # stays the same, not taking account of the user's new choice
有什么想法吗?我尝试使用默认参数而不是数据,但它没有预先填充任何扇区。
答案 0 :(得分:1)
据我所知,直接初始化数据时,wtf Field的内部会丢失正确对象的轨迹。但是还有另一种方法来初始化你的领域。初始化时,将所需数据直接传递给表单。 Field
的处理方法将负责初始化其余部分:
form = CompEditForm(request.form, comp, sectors=[c.id for c in comp.sectors.all()])
答案 1 :(得分:0)
我已经尝试过Sadeghi的解决方案,但是,正如我所说,它只是没有用初始数据填充表格。最后,我找到了sqlalchemy extension for WTForms,我使用了QuerySelectMultipleField:
sectors = QuerySelectMultipleField(query_factory=all_sectors, allow_blank=True)
而不是简单的MultipleSelectField。 all_sectors工厂是使用>
定义的简单查询def all_sectors():
return Sector.query.all()
然而,submiutted表单返回一个queryset对象,而不是通常的Names / ID组合,所以在更新公司数据的代码中我可以简单地说:
for sec in comp.sectors:
comp.sectors.remove(sec)
if form.sectors.data:
for sek in form.sectors.data:
comp.sectors.append(sek)
老实说,我不知道为什么Sadeghi的解决方案对我不起作用,我的解决方案更复杂,更丑陋但是有效。谢谢Sadeghi。