1

I have this form form where each row represents an object filled with inputs.

Here's the snippet of the form:

<form>
<li>
    <select name="network[][layer_type]"><!-- options here --></select>
    <input type="number" name="network[][num_filters]">
    <!-- other parameters here -->
</li>
<li>
    <select name="network[][layer_type]"><!-- options here --></select>
    <input type="number" name="network[][pool_size]">
    <!-- other parameters here -->
</li>
<li>
    <select name="network[][layer_type]"><!-- options here --></select>
    <input type="number" name="network[][num_filters]">
    <!-- other parameters here -->
</li>
</form>

On submitting, I want the output dict to be like this:

{
"network":[
    {"layer_type": "conv2d", "num_filters": 16, "kernel_size": 2, "padding": "valid", "stride": 2},
    {"layer_type": "max_pool2d", "num_filters": 16, "kernel_size": 2, "padding": "valid", "stride": 2},
    {"layer_type": "conv2d", "num_filters": 32, "kernel_size": 3, "padding": "valid", "stride": 2}       
  ]
}

Using request.form.getlist('network[]') returns []. How do I get that output dict using Flask?

1 Answer 1

1

There seems to be a fundamental misunderstanding about flask and the relationship between your code and your templates. First of all, you can't drop code into your HTML template without using Jinja (Flask standard) or some other tool. Using Jinja you can add variables into your HTML template with {{variable}} and add limited logic into your template with {% for item in list %} HTML to loop {% endfor%}. More about Jinja conventions here and here.

Presuming you want the users to use your select and inputs to set layer type and number of filters and that the other details are set in similar fasshion, you will want your template to look like this:

<form>
<li>
    <select name="net1_layer_type_1"><!-- options here --></select>
    <input type="number" name="net1_num_filters_1">
    <!-- other parameters here -->
</li>
<li>
    <select name="net1_layer_type_2"><!-- options here --></select>
    <input type="number" name="net1_num_filters_2">
    <!-- other parameters here -->
</li>
<li>
    <select name="net1_layer_type_3"><!-- options here --></select>
    <input type="number" name="net1_num_filters_3">
    <!-- other parameters here -->
</li>
</form>

Then in your corresponding flask route, you can build this dictionary like this:

networks = {}
networks['network'] = []
networks['network'][0] = {'layer_type': request.form['net1_layer_type_1'], 'num_filters': request.form['net1_num_filters_1'], "kernel_size": 2, "padding": "valid", "stride": 2}

Repeat for the other items.

Using this as a basis, I'm sure you can see how you can make this more dynamic, allowing additional networks with additional members, and using loops to create each network member. Let's say you want to make 4 networks each with 5 memebers, on the route that renders your form, you create the lists "network_count" and "member_count" which look like [1,2,3,4] and [1,2,3,4,5], respectively. Then on your template use a loop to build your form that looks like this:

<form>
    {% for net in network_count %}
        {% for mem in member_count %}
            <li>
                <select name="net{{net}}_layer_type_{{member}}"><!-- options here --></select>
                <input type="number" name="net{{net}}_num_filters_{{member}}">
                <!-- other parameters here -->
            </li>
        {% endfor %}
    {% endfor %}
</form>

Use the same python as before to process, but loop that as well.

Sign up to request clarification or add additional context in comments.

2 Comments

I keep forgetting that there’s Jinja. I actually did the same thing you did there with the form. I guess there is really no way to get a list of objects in one go from a form (unlike in php).
There are. You could, for example, name all of your members the same for each thing you want and then in your route, use request.args.getlist('layer_type') to generate an ordered list of inputs that you could iterate over. I just like things to be as explicit as possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.