Commencez par écrire "import cgi". Ne faites pas "from cgi import *" --- le module définit toutes sortes de noms pour son usage propre ou pour des raisons de compatibilité ascendante que vous ne voudrez pas avoir dans votre espace de noms.
Le mieux est d'utiliser la classe FieldStorage. Les autres classes définies dans ce module servent surtout à assurer la compatibilité ascendante. Instanciez-la une seule fois, sans argument. Le contenu du forumlaire sera lu depuis l'entrée standard ou l'environnement (cela dépend de la valeur de diverses variables d'environnement définies selon le standard CGI). Puisqu'elle peut être alimentée par l'entrée standard, elle ne doit être instanciée qu'une fois.
L'instance de FieldStorage peut être indexée comme un dictionnaire Python, et supporte aussi les méthodes de dictionnaire has_key() et keys(). Les champs de formulaire qui contiennent des chaînes vides sont ignorées et n'apparaissent pas dans le dictionnaire; pour les conserver, utilisez l'argument optionnel "keep_blank_values" quand vous créez l'instance de FieldStorage.
Par exemple, le code suivant (qui suppose que l'entête Content-Type et la ligne vide ont déjà été envoyés) vérifie que les champs nom et adresse ont tous les deux une valeur non vide:
form = cgi.FieldStorage()
form_ok = 0
if form.has_key("nom") and form.has_key("adresse"):
form_ok = 1
if not form_ok:
print "<H1>Erreur</H1>"
print "Veuillez remplir les champs nom et adresse."
return
print "<p>nom:", form["nom"].value
print "<p>adresse:", form["adresse"].value
...suite du traitement du formulaire ici...
Ici les champs, auxquels on accède par "form[key]", sont eux-mêmes des instances de FieldStorage (ou de MiniFieldStorage, selon l'encodage du formulaire). L'attribut value de l'instance produit la valeur chaîne du champ. La méthode getvalue() retourne cette valeur chaîne directement; elle accepte également un second argument optionnel comme valeur par défaut à retourner si la clé demandée est absente.
Si les données de formulaire soumises contiennent plus d'un champ ayant le même nom, l'objet récupéré par "form[key]" n'est pas une instance de FieldStorage ou de MiniFieldStorage mais une liste de telles instances. De même, dans cette situation, "form.getvalue(key)" renverrait une liste de chaînes. Si vous vous attendez à cette possibilté (c'est-à-dire quand votre formulaire HTML contient de multiples champs ayant le même nom), servez-vous de la fonction type() pour savoir si vous avez une seule instance ou une liste d'instances. Par exemple, voici du code qui concatène un nombre quelconque de champs "nomutilisateur", séparés par des virgules:
valeur = form.getvalue("nomutilisateur", "")
if type(valeur) is type([]):
# Plusieurs champs nomutilisateur spécifiés
nomutilisateurs = ",".join(valeur)
else:
# Champ nomutilisateur unique ou non spécifié
nomutilisateurs = valeur
Si un champ représente un fichier téléchargé remontant, l'accès à la valeur via l'attribut value ou la méthode getvalue() lit l'ensemble du fichier dans la mémoire sous forme de chaîne. Il se peut que ce ne soit pas ce que vous souhaitez. Vous pouvez tester s'il s'agit d'un fichier téléchargé en testant soit l'attribut filename ou l'attribut file. Vous pouvez alors lire les données à loisir depuis l'attribut file:
element_fichier = form["fichier_utilisateur"]
if element_fichier.file:
# C'est un fichier téléchargé; on compte les lignes
compteur_lignes = 0
while 1:
ligne = element_fichier.file.readline()
if not ligne: break
compteur_lignes = compteur_lignes + 1
Le draft de standard au sujet des téléchargements de fichiers prévoit la possibilité de remonter plusieurs fichiers depuis un champ unique (avec un encodage récursif multipart/*). Quand cela se produit, l'élément sera un élément FieldStorage ressemblant à un dictionnaire. On peut le déterminer en testant son attribut type, qui doit être multipart/form-data (ou peut-être un autre type MIME correspondant à multipart/*). Dans ce cas, on peut itérer récursivement exactement comme l'objet formulaire de niveau supérieur.
Quand un formulaire est soumis dans le ``vieux'' format (comme la query string ou une partie données unique de type application/x-www-form-urlencoded), les éléments seront en fait des instances de la classe MiniFieldStorage. Dans ce cas, les attributs list, file et filename valent toujours None.