Reputation: 31
I am trying to get user-inputted data from a web page generated in one Python script to submit to another Python script to process that data. In the first python script I have used the following to create a web form to submit data:
print("<form action='newspeciescheck.py' method='post'>")
print("<p>Genus: <input type='text' name='newgenus'/> <p>Species: <input type='text' name='newspecies'/>")
print("<input type='submit' value='Enter'>")
print("</form>\n ")
In the target script I have
formfields = cgi.FieldStorage()
newgenus = formfields.getValue('newgenus')
newspecies = formfields.getValue('newspecies')
However, when I try to run this, cgitb throws an error telling me that:
A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred.
C:\Abyss Web Server\htdocs\pyscripts\newspeciescheck.py in ()
21
22 formfields = cgi.FieldStorage()
=> 23 newgenus = formfields.getValue('newgenus')
24 status=''
25 if newgenus==None:
newgenus undefined, formfields = FieldStorage(None, None, [MiniFieldStorage('newg...phis'), MiniFieldStorage('newspecies', 'fabae')]), formfields.getValue undefined
C:\Users\John\AppData\Local\Programs\Python\Python36\lib\cgi.py in __getattr__(self=FieldStorage(None, None, [MiniFieldStorage('newg...phis'), MiniFieldStorage('newspecies', 'fabae')]), name='getValue')
583 def __getattr__(self, name):
584 if name != 'value':
=> 585 raise AttributeError(name)
586 if self.file:
587 self.file.seek(0)
builtin AttributeError = <class 'AttributeError'>, name = 'getValue'
AttributeError: getValue
args = ('getValue',)
with_traceback = <built-in method with_traceback of AttributeError object>
So why do my submitted values end up in MiniFieldStorage rather than normal FieldStorage? More importantly how do I get them to end up as normal FieldStorage?
Upvotes: 3
Views: 813
Reputation: 55799
You are seeing the error because you are trying to access FieldStorage
's getValue
method, it doesn't have one - the correct method name is getvalue
- note the lowercase v.
However, this is the answer to your question about FieldStorage
vs MiniFieldStorage
According to the documentation, whether values end up as FieldStorage
or MiniFieldStorage
instances depends on the encoding type (the enctype
attribute) of the form used to submit them.
The file upload draft standard entertains the possibility of uploading multiple files from one field (using a recursive multipart/* encoding). When this occurs, the item will be a dictionary-like FieldStorage item. This can be determined by testing its type attribute, which should be multipart/form-data (or perhaps another MIME type matching multipart/*). In this case, it can be iterated over recursively just like the top-level form object.
When a form is submitted in the “old” format (as the query string or as a single data part of type application/x-www-form-urlencoded), the items will actually be instances of the class MiniFieldStorage.
The default encoding type is application/x-www-form-urlencoded
So if you want to force the use of FieldStorage
, your form declaration needs to be
<form action='newspeciescheck.py' method='post' enctype="multipart/form-data">
See this answer for a discussion of form encodings, and why you might select one or the other.
Upvotes: 2