3

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?

John L73
  • 31
  • 3
  • Welcome to Stackoverflow. Please edit your question to include a clear problem description. For guidance please check the [how to ask](https://stackoverflow.com/help/how-to-ask) page and [how to create a minimal example](https://stackoverflow.com/help/mcve). – 5th Aug 10 '18 at 15:43

1 Answers1

2

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.

snakecharmerb
  • 28,223
  • 10
  • 51
  • 86