1

I have a javascript code to create all combination of product based on characteristics that are added dynamically. HTML eesult of this script is:

<form id="myWizard" action="" method="post" role="form">    
<table>
        <tbody>
          <tr>
            <td>1</td>
            <td><select id="combination[0].product" name="combination[0].product">
              <option value="25">
                product_desc pc.10
              </option>
              <option value="26">
                product_desc pc.5
              </option>
              <option value="21">
                product_desc
              </option>
            </select></td>
            <td><input readonly="readonly" value="5.00" id="combination[0].price" name="combination[0].price" class="form-control" type="text" /></td>
            <td><input readonly="readonly" value="a" id="combination[0].color" name="combination[0].color" class="form-control" type="text" /></td>
            <td><input readonly="readonly" value="1" id="combination[0].quantity" name="combination[0].quantity" class="form-control" type="text" /></td>
          </tr>

          <tr>
            <td>2</td>
            <td><select id="combination[1].product" name="combination[1].product">
              <option value="25">
                product_desc pc.10
              </option>
              <option value="26">
                product_desc pc.5
              </option>
              <option value="21">
                product_desc
              </option>
            </select></td>
            <td><input readonly="readonly" value="5.00" id="combination[1].price" name="combination[1].price" class="form-control" type="text" /></td>
            <td><input readonly="readonly" value="a" id="combination[1].color" name="combination[1].color" class="form-control" type="text" /></td>
            <td><input readonly="readonly" value="5" id="combination[1].quantity" name="combination[1].quantity" class="form-control" type="text" /></td>
          </tr>

          <tr>
            <td>5</td>
            <td><select id="combination[8].product" name="combination[8].product">
              <option value="25">
                product_desc pc.10
              </option>
              <option value="26">
                product_desc pc.5
              </option>
              <option value="21">
                product_desc
              </option>
            </select></td>
            <td><input readonly="readonly" value="5.00" id="combination[8].price" name="combination[8].price" class="form-control" type="text" /></td>
            <td><input readonly="readonly" value="c" id="combination[8].color" name="combination[8].color" class="form-control" type="text" /></td>
            <td><input readonly="readonly" value="50" id="combination[8].quantity" name="combination[8].quantity" class="form-control" type="text" /></td>
          </tr>
        </tbody>
      </table> 
</form>

Of course there can be many more characteristics (for example type, material...).

How can I process it with request.POST? I tried getlist but without success. For the record I use Django 1.9. Is there any way I can get list of dictionaries from this request, so I would get something like:

list = [{'product_id': '25', 'price':'5.00', 'color':'c', 'quantity':'50'},
{'product_id': '26', 'price':'5.00', 'color':'a', 'quantity':'1'},
{'product_id': '21', 'price':'5.00', 'color':'a', 'quantity':'5'} 
]

or anything similiar?

3
  • Can we assume the table is surrounded by a <form method="POST"> element? Commented Feb 9, 2018 at 0:23
  • Yes. It is inside <form> elalement. I updated question. Commented Feb 9, 2018 at 0:31
  • There are no prices like 12.22 or 2.22 in the table (they're all 5.00), not are there colours like black or blue ('a' or 'c'). Please make sure your example input corresponds to your wanted example output. Commented Feb 9, 2018 at 0:45

1 Answer 1

2

One solution is to straightforwardly manipulate the POST data, for example like this:

results = defaultdict(dict)
for k, v in request.POST.items():
    _, no, key = re.split(r'\[(?P<no>\d+)\]\.', k, maxsplit=2)
    results[no][key] = v
data = []
for value in results.values():
    data.append(value)

The resulting data looks like (with the current table data):

[{'product': '25', 'price': '5.00', 'color': 'a', 'quantity': '1'}, 
 {'product': '25', 'price': '5.00', 'color': 'a', 'quantity': '5'}, 
 {'product': '25', 'price': '5.00', 'color': 'c', 'quantity': '50'}]

This does not take care of POSTed fields that don't follow the "combination[<digit>].name" convention; you'd have to weed those out yourself (e.g., by wrapping the code above in an exception if the regular expression fails, or by using a simple if statement).
There's also no conversion for numbers to float or integer, since Django has no way of knowing what the input type is, and thus assumes everything is a string.


You may want to rethink your form generation, especially if you want to use Django. Using Django forms (or model forms even) automatically gives you the right output format, and provides proper conversions and type checking.

Have a look at Django's formsets, which is precisely meant for generating multiple forms, and seems to be pretty close to your example form.

(Note: the version 1.9 documentation has, as of current, a red bar above it stating it's an insecure and unsupported version of Django. See if you can upgrade to 2.0.)

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

Comments

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.