Python CGI で 掲示板みたいなものを作る~FieldStorage編~ [プログラム三昧]
前回の記事Python CGI で 掲示板みたいなものを作る~POST編~では、 "cgi.parse_qs()" を使って query を取り出す方法を使いました。 今回は、こんどはPOSTを受ける方法。で紹介されていた "cgi.FieldStorage()" を使用してみます。 もしかして、こっちが、本流なのかな?
FORMの構成
HTML文書は、タイトルと呼び出すCGIが変わっただけです。 もう、説明はいらないよね。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <!-- $Id: visitor_world5.html,v 1.1 2009/06/06 05:07:43 noritan Exp $ --> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" > <head profile="http://www.w3.org/2005/10/profile"> <title>VISITOR WORLD 5</title> </head> <body> <h1>VISITOR WORLD 5</h1> <form action="./visitor_world5.cgi" method="post"> <div> <textarea name="message" rows="4" cols="40"></textarea> </div> <p> <input type="submit" value="Submit" /> <input type="reset" value="Clear" /> </p> </form> </body> </html>
query データベースの作り方と使い方
前回は query のデータベースを "cgi.parse_qs()" メソッドで作成していましたが、今回は、 "cgi.FieldStorage()" オブジェクトとして生成します。
- BEFORE
# Get a POST data. content_length = int(os.environ['CONTENT_LENGTH']) query = cgi.parse_qs(sys.stdin.read(content_length))
- AFTER
# Get a POST data. form = cgi.FieldStorage()
今まで苦労してたのが、ウソみたいだ。 出来上がったデータベースは、 "cgi.parse_qs" で作成した方は、 Python のデータベースオブジェクトそのものでしたが、 "cgi.FieldStorage()" の方は再帰的な木構造を持っています。 そのため、目的の要素を取り出す方法も異なっています。
- BEFORE
# Get and escape a MESSAGE message_key = 'message' if message_key in query: message = urllib.quote(cgi.escape(query[message_key][0])) else: message = ""
- AFTER
# Get and escape a MESSAGE message_key = 'message' if message_key in form: message = urllib.quote(cgi.escape(str(form.getvalue(message_key)))) else: message = ""
"FieldStorage" から要素を取り出すには、色々なメソッドがあります。 今回は、手ごろなところで、 "FieldStorage.getvalue()" を使いました。
先に書いたように、 FieldStorage クラスは木構造を持っています。 したがって、 "FieldStorage.getvalue()" メソッドで取り出した値が文字列であるという保証はどこにもありません。 その正体不明の要素を確実に文字列にするため、 "str()" 関数を使っています。 これで、確実に何らかの文字列が得られます。
CGIの出来上がり
という訳で、できあがりました。
#!/usr/local/bin/python # $Id: visitor_world5.cgi,v 1.1 2009/06/06 05:07:43 noritan Exp $ import os import sys import cgi import urllib import time import cgitb # Show error as a page description. sys.stderr = sys.stdout cgitb.enable() # Database releated information db_file = "visitor.sqlite" table_name = "visitor" command = "/usr/local/bin/sqlite3 %s" % (db_file) # Get a POST data. form = cgi.FieldStorage() # Get Current time now = time.time() # Get and escape a MESSAGE message_key = 'message' if message_key in form: message = urllib.quote(cgi.escape(str(form.getvalue(message_key)))) else: message = "" # Compose a SQL sql = "SELECT time, description FROM %(table)s ORDER BY time DESC;" if len(message) > 0: sql = \ "INSERT INTO %(table)s VALUES (%(now)f, \"%(message)s\");\n" \ + sql # Show HTML header print """Content-type: text/html <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > <head profile="http://www.w3.org/2005/10/profile"> <link rel="icon" href="/favicon.png" type="image/png" /> <title>VISITOR WORLD 5</title> </head> <body> <h1>VISITOR WORLD 5</h1> """ # Access to the DATABSE (pipe_out, pipe_in) = os.popen2(command) pipe_out.write( sql % {"table":table_name, "now":now, "message":message} ) pipe_out.close() # Show a list of visitor record print """<dl> """ # Make a list of messages try: for line in pipe_in: field = line.split("|") asctime = time.strftime( "%Y-%m-%d (%A) %H:%M:%S", time.localtime(float(field[0])) ) message = urllib.unquote(field[1]) print "<dt>%s</dt><dd>%s</dd>\n" % (asctime, message) finally: pipe_in.close() # Show footer print """ </dl> </body> </html> """
参考サイト
- VISITOR WORLD 5
- "FORM"入力ページは、ここにありますので、お試しください。
- Python v2.6.2 documentation
- python.org にあるオンラインドキュメントです。 現在、私が使っているサーバにインストールされている python は、 version 2.4.5 なのですが、ここには、原稿執筆時点で version 2.6.2 が置いてあります。 ちょっと、注意しながら使わなくては。
- 21.2. cgi — Common Gateway Interface support.
- cgi パッケージ関連のマニュアルです。 FieldStorage クラスの解説は、これだけなのかな?
コメント 0