Begin by writing import cgi
. Don't use from cgi import *
- the
module defines all sorts of names for its own use or for backward
compatibility that you don't want in your namespace.
It's best to use the FieldStorage
class. The other classes define in this
module are provided mostly for backward compatibility. Instantiate it
exactly once, without arguments. This reads the form contents from
standard input or the environment (depending on the value of various
environment variables set according to the CGI standard). Since it may
consume standard input, it should be instantiated only once.
The FieldStorage
instance can be accessed as if it were a Python
dictionary. For instance, the following code (which assumes that the
Content-type
header and blank line have already been printed) checks that
the fields name
and addr
are both set to a non-empty string:
form = cgi.FieldStorage() form_ok = 0 if form.has_key("name") and form.has_key("addr"): if form["name"].value != "" and form["addr"].value != "": form_ok = 1 if not form_ok: print "<H1>Error</H1>" print "Please fill in the name and addr fields." return ...further form processing here...
Here the fields, accessed through form[key]
, are themselves instances
of FieldStorage
(or MiniFieldStorage
, depending on the form encoding).
If the submitted form data contains more than one field with the same
name, the object retrieved by form[key]
is not a (Mini)FieldStorage
instance but a list of such instances. If you expect this possibility
(i.e., when your HTML form comtains multiple fields with the same
name), use the type()
function to determine whether you have a single
instance or a list of instances. For example, here's code that
concatenates any number of username fields, separated by commas:
username = form["username"] if type(username) is type([]): # Multiple username fields specified usernames = "" for item in username: if usernames: # Next item -- insert comma usernames = usernames + "," + item.value else: # First item -- don't insert comma usernames = item.value else: # Single username field specified usernames = username.value
If a field represents an uploaded file, the value attribute reads the entire file in memory as a string. This may not be what you want. You can test for an uploaded file by testing either the filename attribute or the file attribute. You can then read the data at leasure from the file attribute:
fileitem = form["userfile"] if fileitem.file: # It's an uploaded file; count lines linecount = 0 while 1: line = fileitem.file.readline() if not line: break linecount = linecount + 1
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 have the value multipart/form-data
(or
perhaps another string beginning with multipart/
It 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
. In this case,
the list, file and filename attributes are always None
.