2008年11月14日 開始
× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
11.2.2 cgi モジュールを使う先頭には "import cgi" と書いてください。"from cgi import *"と書いてはいけません -- このモジュールは以前のバージョンとの互換性を持たせるために内部で呼び出す名前を多数定義しており、それらがユーザの名前空間に存在する必要はありません。 新たにスクリプトを書く際には、以下の一行を付加するかどうか検討してください:
import cgitb; cgitb.enable() これによって、特別な例外処理が有効にされ、エラーが発生した際にブラウザ上に詳細なレポートを出力するようになります。ユーザにスクリプトの内部を見せたくないのなら、以下のようにしてレポートをファイルに保存できます:
import cgitb; cgitb.enable(display=0, logdir="/tmp") スクリプトを開発する際には、この機能はとても役に立ちます。 cgitb が生成する報告はバグを追跡するためにかかる時間を大きく減らせるような情報を提供してくれます。スクリプトをテストし終わり、正確に動作することを確認した後はいつでも 入力されたフォームデータを取得するには、 FieldStorage クラスを使うのが最良の方法です。このモジュールで定義されている他のクラスのほとんどは以前のバージョンとの互換性のためのものです。インスタンス生成は引数なしで必ず 1 度だけ行います。これにより、標準入力または環境変数からフォームの内容が読み出されます (どちらから読み出されるかは、CGI 標準に従って設定されている複数の環境変数の値によって決められます)。インスタンスが標準入力を使うかもしれないので、インスタンス生成を行うのは一度だけにしなければなりません。 FieldStorage のインスタンスは Python の辞書のようにインデクスを使った参照ができ、標準の辞書に対するメソッド has_key() と keys() をサポートしています。組み込みの関数 len() もサポートされています。空の文字列を含むフォームのフィールドは無視され、辞書上にはありません; そういった値を保持するには、 FieldStorage のインスタンスを生成する時にオプションの keep_blank_values キーワード引数を true に設定してください。 例えば、以下のコード (Content-Type: ヘッダと空行はすでに出力された後とします) は
form = cgi.FieldStorage() if not (form.has_key("name") and form.has_key("addr")): print "<H1>Error</H1>" print "Please fill in the name and addr fields." return print "<p>name:", form["name"].value print "<p>addr:", form["addr"].value ...further form processing here... ここで、"form[key]" で参照される各フィールドはそれ自体が FieldStorage (または MiniFieldStorage 。フォームのエンコードによって変わります) のインスタンスです。インスタンスの属性 value フィールドの文字列値になります。 getvalue() メソッドはこの文字列値を直接返します。 getvalue() は 2 つめの引数にオプションの値を与えることができ、リクエストされたキーが存在しない場合に返されるデフォルトの値になります。 入力されたフォームデータに同じ名前のフィールドが二つ以上あれば、 "form[key]" で得られるオブジェクトは FieldStorage や MiniFieldStorage のインスタンスではなく、それらインスタンスからなるリストになります。同じく、この状況では、 "form.getvalue(key)" は文字列を要素とするリストを返します。もしこうした状況が起こりうると思われるなら (HTML のフォームに同じ名前をもったフィールドが複数含まれているのなら) 、組み込み関数 isinstance() を使って、返された値が単一のインスタンスかインスタンスのリストかを調べてください。例えば、以下のコードは任意の数のユーザ名フィールドを結合し、コンマで分割された文字列にします:
value = form.getvalue("username", "") if isinstance(value, list): # Multiple username fields specified usernames = ",".join(value) else: # Single or no username field specified usernames = value フィールドがアップロードされたファイルを表す場合、value 属性または getvalue() メソッドを介してアクセスされた値はファイルの内容を全て文字列としてメモリ上に読み込みます。これは望ましくない機能かもしれません。アップロードされたファイルがあるかどうかは filename 属性および file 属性のいずれかで調べることができます。その後、以下のようにして 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/* エンコーディングを使うことで) 複数のファイルがアップロードされる可能性を受け入れています。この場合、アイテムは辞書形式の FieldStorage アイテムとなります。複数ファイルかどうかは type 属性が multipart/form-data (または multipart/* にマッチする他の MIME 型) になっているかどうか調べることで判別できます。この場合、トップレベルのフォームオブジェクトと同様にして再帰的に個別処理できます。 フォームが ``古い'' 形式で入力された場合 (クエリ文字列または application/x-www-form-urlencoded データの単一の部分の場合) アイテムは実際には MiniFieldStorage クラスのインスタンスになります。この場合、list 、file 、および filename 属性は常に
PR |
カテゴリー
最新記事
(05/13)
(06/22)
(06/22)
(12/20)
(12/19)
(10/08)
(09/20)
(05/31)
(05/10)
(04/18)
(02/08)
(01/30)
(01/29)
(01/29)
(01/07)
(01/06)
(12/30)
(12/30)
(12/26)
(12/24)
カレンダー
リンク
フリーエリア
最新CM
最新TB
プロフィール
HN:
No Name Ninja
性別:
非公開
ブログ内検索
アーカイブ
最古記事
(05/10)
(11/14)
(11/17)
(11/21)
(11/30)
(11/30)
(12/02)
(12/02)
(12/04)
(12/06)
(12/06)
(12/06)
(12/06)
(12/07)
(12/07)
(12/07)
(12/07)
(12/13)
(12/13)
(12/19)
P R
カウンター
ブログの評価 ブログレーダー
|