烧瓶预填充形式

时间:2014-09-08 21:07:20

标签: flask flask-sqlalchemy flask-wtforms

我有一个奇怪的问题,烧瓶,烧瓶重量和烧瓶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

有什么想法吗?我尝试使用默认参数而不是数据,但它没有预先填充任何扇区。

2 个答案:

答案 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。