3

I'm trying to fill out a web form using python requests. Does anyone know the correct syntax when there is a drop down (option list)?

I can successfully post to the text boxes on the form, but not the option list

import requests

URL = 'http://127.0.0.1:8000/recoater/new/'
payload = {
   'data': '40',
   'machine': '"1">MachineA<',
}

r = requests.post(URL, data=payload)
print (r)
print(r.text)

Returns this:

<ul class="errorlist"><li>Select a valid choice. That choice is not one of 
the available choices.</li></ul>
<p><label for="id_machine">Machine:</label> <select name="machine" required 
id="id_machine">
<option value="">---------</option>
<option value="1">MachineA</option>
MattG
  • 1,682
  • 5
  • 25
  • 45

1 Answers1

4

For a <select>..</select>, the POST data sends the value=".." of the selected <option>, so in case you want MachineA, you should send it with 'machine': '1', as payload:

import requests

URL = 'http://127.0.0.1:8000/recoater/new/'
payload = {
   'data': '40',
   'machine': '1',
}

r = requests.post(URL, data=payload)
print (r)
print(r.text)

The Django forms (or other mechanisms that handle the request) have logic in place to map this value back to the machine that is associated with this value: after all, the text in the option is just a textual representation of the Machine object, it can contain a lot of (extra) data that is not displayed (or is displayed, but in a non-structured way).

So a browser will for a webpage:

<select name="machine" required id="id_machine">
    <option value="">---------</option>
    <option value="1">MachineA</option>
</select>

Send in the POST data an entry that associates the name of the <select> (here 'machine') that is associated with the value of the option picked (here '' or '1'). Just like a <input name="data" type="text"> has a value parameter as well that is set to the value you enter in the textfield.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Thank you for the response, that worked! However.. I am getting a pretty huge error stack now. Although it is successfully posting the data to the server, this error message is beyond my skills. stack: https://pastebin.com/t2AhSN05 – MattG Aug 25 '18 at 13:16
  • @MattG: do you have "the source code of the view" behind this request. Looks like either the server does a large amount of work, and the connection has timed out, or even forced a disconnect): https://github.com/requests/requests/issues/4413 – Willem Van Onsem Aug 25 '18 at 13:20
  • @MattG: what if you use `method_decorator`: https://stackoverflow.com/a/27315856/67579 – Willem Van Onsem Aug 25 '18 at 13:41
  • Perhaps this should branch off into a separate question. I think it has something to do with the CSRF decorator. I tried to remove this from the view, and add it to the urls.py instead, and am still getting the same error. It is strange becuase the post request is successful, it is something that happens after the POST. – MattG Aug 25 '18 at 13:41
  • Getting closer I think.. after adding the method_decorator I am now getting: https://pastebin.com/JAr14NaZ – MattG Aug 25 '18 at 13:48
  • @MattG: it looks to me that now the `csrf` is required again, so the POST is not processed (since the CSRF check fails) – Willem Van Onsem Aug 25 '18 at 13:50
  • Thanks again for the help @Willem Van Onsem. I changed my view from a class based view, to a function based view, and this solved the problem. Just don't ask me how! Django magic I guess. – MattG Aug 25 '18 at 16:05