在 python 烧瓶中将整数从视图传递到表单

Pass integer from view to form in python flask

我有一个带有 queryselectfield 的 wtform,当前填充了数据库中所有团队的数据:

class PitScoutingForm(FlaskForm):
    team = QuerySelectField(
        query_factory=lambda: Teams.query.all(), get_label='number')

和视图:

@app.route('/competitions/pit-scouting', methods=['GET', 'POST'])
@login_required
def pit_scouting():
    form = PitScoutingForm(request.values)
    form.team.choices = [(a.id, a.number) for a in
                         Teams.query.order_by('number')]

一切正常。但是团队列表越来越大,我想将显示在该字段中的团队限制为当前选择的比赛,所以我将视图更改为

@app.route('competitions/<int: comp_id>/pit-scouting', methods=['GET', 'POST'])

但我不确定如何将 comp_id 从视图传递到表单,以便我可以过滤比赛 ID,这样我只能获得参加该比赛的球队。我看到 this entry 但我不太明白解决方案。任何指点表示赞赏。

您在视图中使用 comp_id 仅 select 该比赛的球队。将 comp_id 更改为您的 Teams Class.

中的任何名称
@app.route('competitions/<int: comp_id>/pit-scouting', methods=['GET',  'POST'])
@login_required
def pit_scouting(comp_id):
    form = PitScoutingForm(request.values)
    form.team.choices = [(a.id, a.number) for a in Teams.query.filter_by(comp_id=comp_id).order_by('number')]

来自Flask Documentation on URL Route Registration

Variable parts are passed to the view function as keyword arguments.

这意味着您只需要更新视图函数以将 comp_id 作为参数,如下所示:

@app.route('competitions/<int: comp_id>/pit-scouting', methods=['GET', 'POST'])
@login_required
def pit_scouting(comp_id):
    form = PitScoutingForm(request.values)
    form.team.choices = [(a.id, a.number) for a in
                     Teams.query.order_by('number')]

感谢各位指点,你们指引了我一个有帮助的方向。我找到了另一个解决方案,建议使用普通 select 字段,然后在 init 中加载选项,而不是像这样:

class PitScoutingForm(FlaskForm):
    team = SelectField('Team', coerce=int)
    ...
    def __init__(self, *args, **kwargs):
        super(PitScoutingForm, self).__init__(*args, **kwargs)
        self.team.choices = [(a.id, a.number) for a in Teams.query.order_by('number')]

然后我的观点(忽略 sql...有时它比 sqlalchemy 语法更容易)保持不变 wrt 设置选项,除了使用传递给查看。

@app.route('/pit-scouting/', defaults={'comp': 2}, methods=['GET', 'POST'])
@app.route('/pit-scouting/competitions/<int:comp>', methods=['GET', 'POST'])
@login_required
def pit_scouting(comp):
    sql_text = '''query here'''.format(comp)
    result = db.engine.execute(sql_text)

    form = PitScoutingForm(request.values)
    form.team.choices = [(a.id, a.number) for a in result]