まず最初に"import cgi"が必要です。 "from cgi import *"では駄目です -- あなたの名前空間では必要でないあらゆる種類の名前が、 モジュール自身と互換性のために定義されています。
FieldStorageクラスを使うのがベストです。 このモジュールで定義される他のクラスは、ほとんどが互換性のために提供されています。 FieldStorageクラスは確実に一度だけ、引数なしでインスタンス化されなければなりません。 これでフォームの内容が標準入力か環境(変数)から読み取られます。 (どちらの方法で読み取られるかは、CGI標準にしたがって設定されたいろいろな環境変数に依存します。) 標準入力が使われることがあるので、インスタンス化は一度だけなのです。
FieldStorageインスタンスはパイソンの辞書のように扱えます。 例えば、次のコードではnameとaddrフィールドは 両方空ではないことをチェックしています。 (Content-typeヘッダと空行はこの前に出力されているものとします。):
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 ...この後にフォームの処理が続く...
このform[key]で参照されるフィールドは、 FieldStorageインスタンス自身です。 (あるいは、フォームのエンコード方法に依存しますが、MiniFieldStorageかも)
フォームが同じ名前のフィールドを複数含んでいた場合には、form[key]は
(Mini)FieldStorageインスタンスではなく、インスタンスのリストになります。
こうなる可能性があるときは
(同じ名前のフィールドが複数あるような HTMLフォームを使う場合には)、
type()
関数でインスタンスかそのリストかを調べてください。
例えば、いくつかのユーザ名のフィールドをコンマで区切る場合のコードは:
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
フィールドがファイルのアップロードを示している場合、 ファイルが丸ごと文字列としてメモリに読み込まれます。 これは本意ではないかもしれません。 そんなときは、filename属性か、file属性を見ることによってアップロードされたファイルを 調べることができます。 そうすれば安心(reasure?)してfile属性からデータを読むことができます:
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
ファイルのアップロードのドラフトでは、一つのフィールドからの (再帰的なmultipart/*を使う) 複数のファイルのアップロードの可能性について述べています。 この場合は、アイテムは辞書のような FieldStrageアイテムとなるでしょう。 そのときは typemultipart/form-data(または多分、multipart/で始まる別の文字列) という値を持っているべきです。 この場合、アップロードされたものは、 最上位の formオブジェクトのような再帰的な繰り返しになります。
フォームが、「古い」フォーマットで(query stringか application/x-www-form-urlencoded の単一データとして)送信された場合、アイテムは 実際 MiniFieldStorageクラスのインスタンスに なるでしょう。 この場合、ファイル・ファイル名属性のリストはいつも Noneです。
guido@python.org