xGlorify
xGlorify

Reputation: 119

Dynamically Update WTForm with SQL-Alchemy query

I am trying to have a form dynamically update by retrieving information from my table then display one of the columns in a SelectField. When I type an asset tag, select a Task Title and hit submit simply nothing happens.

EDIT: I should add the form is updating fine - all my selections are there and being retrieved successfully. It's simply not executing any of my view function after that.

My form is as follows;

class AssignTasksForm(Form):
    asset_tag = StringField('asset_tag', validators=[DataRequired()])
    task_title = SelectField('task_title', validators=[DataRequired()])

My view function;

@tasks_blueprint.route('/assign_tasks', methods=['GET', 'POST'])
@login_required
def assign_tasks():
    form = AssignTasksForm()
    form.task_title.choices = [(tc.task_id, tc.task_title) for tc in Tasks.query.order_by('task_id')]
    if request.method == 'POST':
        if form.validate_on_submit():
            try:
                asset_tag = form.asset_tag.data
                asset = Motor.query.filter_by(asset_tag = asset_tag).first_or_404()
                task_title = form.task_title.data
                task = Tasks.query.filter_by(task_title = task_title).first_or_404()
                task.asset_tasks.append(asset)
                db.session.commit()
            except Exception as e:
                flash(e)
                db.session.rollback()
    return render_template('assign_tasks.html', form=form)

My terminal output leads me to believe the form may be becoming invalidated after the data is retrieved from the table:

2016-08-17 18:21:56,568 INFO sqlalchemy.engine.base.Engine {'id_1': 1, 'param_1': 1}
2016-08-17 18:21:56,577 INFO sqlalchemy.engine.base.Engine SELECT tasks."Task Title" AS "tasks_Task Title", tasks."Description" AS "tasks_Description", tasks.task_id AS tasks_task_id
FROM tasks ORDER BY tasks.task_id
2016-08-17 18:21:56,577 INFO sqlalchemy.engine.base.Engine {}
108.168.36.217 - - [17/Aug/2016 18:21:56] "POST /tasks/assign_tasks HTTP/1.1" 200 -

You can see it run the query outlined in view and then post the webpage but it simply does not continue executing the rest of the view function.

Here is my template:

{% extends "basehead.html" %}
{% block content %}
  <center>
    <div class="container">
      <h2>Assign Tasks Below</h2>
      <br>
      <form action="" method="post" name="submit">
      {{ form.hidden_tag() }}
     <p>
        {{ form.asset_tag(placeholder=" Enter Asset Tag") }}
     </p>
     <p>
         {{ form.task_title }}
     </p>
        <input class="btn btn-default" type="submit" value="Submit">
      </form>
    </div>
    {% if result_message %}
    <br>
       <p class="result_message"> {{ result_message }} </p>
    </br>
    {% endif %}
    </center>
{% endblock %}

Upvotes: 0

Views: 614

Answers (2)

xGlorify
xGlorify

Reputation: 119

I found the issue,

WTForms wants to handle the returned data from the query as a string, however the IDs (integers) obviously are not strings, which must be why validation fails.

By adding coerce=int to my task_title object in my form definition WTForms now knows to handle it as an int and passes validation.

Fixed code:

class AssignTasksForm(Form):
    asset_tag = StringField('asset_tag', validators=[DataRequired()])
    task_title = SelectField('task_title', coerce=int, validators=[DataRequired()])

Source: Not a Valid Choice for Dynamic Select Field WTFORMS

Upvotes: 0

Adam
Adam

Reputation: 4172

Try the following. http://hastebin.com/obojivosar.py

You don't need to check if request.method == "POST": I simply moved the populating of the choices to the bottom of the view. I never touch the form before validate_on_submit Also how does result_message get into the context of the template?

Upvotes: 1

Related Questions