0

Using Formfields and Fieldlists with WTForms submits a dictionary of items with the form submit.

Here's an example:

data = {
...   "stepset-0-recipe_step_id": "5",
...   "stepset-0-recipe_step_name": "boil rice",
...   "stepset-0-recipe_step_temp": "42.0",
...   "stepset-1-recipe_step_id": "6",
...   "stepset-1-recipe_step_name": "heat rice",
...   "stepset-1-recipe_step_temp": "57.0",
}

I get that I need to parse through this but I'm struggling a bit with the data structure.

Every 3 lines need to be added to an entry in the database. So how do I go about doing this?

I'm currently looking into regex to grab the number in the key, and the 'recipe_step_id' etc to match the values in the database row.

The other question is, I'm assuming that the id is important to have here as the Fieldlist doesn't seem to submit a database object, am I correct? Do I need to hide this field somehow (I don't want users to be able to edit or see it really).

jt196
  • 17
  • 5

1 Answers1

0

So the answer was considerably more complex than I'd have thought for a WTForms built in function. I found a way here to change the flattened dictionary into a nested dictionary. My function is almost identical aside from the split right method:

def nest_once(inp_dict):
    out = {}
    if isinstance(inp_dict, dict):
        for key, val in inp_dict.items():
            if '-' in key:
                head, tail = key.rsplit('-', 1)

                if head not in out.keys():
                    out[head] = {tail: val}
                else:
                    out[head].update({tail: val})
            else:
                out[key] = val
    return out

Then I iterated through that list, adding specified values to the database:

@app.route('/recipe/recipesteps/<int:recipe_id>/update', methods=['GET', 'POST'])
def updaterecipesteps(recipe_id):
    recipe = Recipe.query.get_or_404(recipe_id)
    data = request.form
    nested_data = nest_once(data)
    for key, val in nested_data.items():
        recipe_step_id = val['recipe_step_id']
        recipe_step = RecipeSteps.query.get_or_404(recipe_step_id)
        recipe_step_temp = val['recipe_step_temp']
        recipe_step_name = val['recipe_step_name']
        recipe_step.name = recipe_step_name
        recipe_step.step_temp = recipe_step_temp
        db.session.commit()
    return redirect(url_for('recipe', recipe_id=recipe.id))

I'll be cleaning this up a bit at some point but it's currently working.

jt196
  • 17
  • 5