FrontPage
>>
Log
>>
DTMLTreeDB
last edited 5 years ago by jack
- <dtml-tree> でDatabase の階層構造をたどる方法
実装例は http://ns.jk.to/jack/TreeDB/ で、どーぞ
現状動いてません
- Databaseをつくる。Z MySQL Database Connectionを前提としてます(それしかないので(^^;;)。
・ table を作る。とりあえず下記のテーブルを前提とします。
CREATE TABLE unit ( unitid INTEGER UNIQUE NOT NULL AUTO_INCREMENT, type INTEGER, parent INTEGER, name VARCHAR(100), postal CHAR(7), address VARCHAR(100), PRIMARY KEY(unitid));
以下では、メソッドを個別に書いてませんが、まとめる方法を PythonScript に書いてあります
さて、Z SQL method とPython Script をこれから5本「ずつ」書きます。一つ一つは短いのであきらめてください。
- select, update, insert
パラメータリストは type,parent,name,postal,address として
- UnitInsert:
container.UnitInsertSQL(unitid=0,type=type,parent=parent,name=name,postal=postal,address=address) return container.REQUEST.RESPONSE.redirect(container.REQUEST.HTTP_REFERER)
- UnitInsertSQL:
Arguments は unitid type parent name postal address
INSERT INTO unit VALUES (<dtml-sqlvar unitid type=int>, <dtml-sqlvar type type=int>, <dtml-sqlvar parent type=int>, <dtml-sqlvar name type=string>, <dtml-sqlvar postal type=string>, <dtml-sqlvar address type=string>)
- みたいな Z SQL method を作ります。これは insert で unitid は auto_incrementだよりになってます。
- 同様に、update,selectも作ります。argumentは省略してますが、いっぱいもしくはちょっと書くだけです。
- UnitUpdate:
container.UnitUpdateSQL(unitid=unitid,type=type,parent=parent,name=name,postal=postal,address=address) return container.REQUEST.RESPONSE.redirect(container.REQUEST.HTTP_REFERER)
- UnitUpdateSQL:
UPDATE unit SET parent=<dtml-sqlvar parent type=int>, name=<dtml-sqlvar name type=string>, postal=<dtml-sqlvar postal type=string>, address=<dtml-sqlvar address type=string> WHERE unitid = <dtml-sqlvar unitid type=int>
- UnitSelect:
result = container.UnitSelectSQL(unitid=str(unitid)) dict = result.dictionaries() return dict[0]
- UnitSelectSQL:
SELECT * FROM unit WHERE <dtml-sqltest unitid type=int>
- 以上で、基本的なDBのハンドリングができるようになりました。あとは dtml-tree方面です。
dtml-tree では、+とかのとこで分岐を判断するやつとして、branches_exprというのがあって、そこで関数を指定できます。そのための関数を書きます。
- LookupChild:
num = int(parent) if num > 0: r = container.LookupChildSQL(parent=num) else: num = -num r = container.LookupUnitSQL(unitid=num) return r
一見意味不明ですが、あまり実装としては美しくないです。parent をパラメータでとってますが、負なら、そのもののユニットをとってきて、正ならそのものが「親」であるのをもってこいになります。
でも、いろいろ書くと、トップ固定のネタとしても重要かも、と思わなくもないっす。
- LookupChildSQL: parent
SELECT unitid, name FROM unit WHERE <dtml-sqltest parent type=int>
- LookupUnitSQL: unitid
SELECT unitid, name FROM unit WHERE <dtml-sqltest unitid type=int>
の、どちらかを呼びます。
あと、直接はたいして関係ないのだけど、一応、formの引数は""でかこったほうがいいみたいなので、勝手にそうするスクリプトをひとつ。
- addQuote: p
return '"
+str(p)+"'
- UnitInsert:
うーん、こんだけ。
- 最後にDTML_Methodを作りますね。
<dtml-var standard_html_header>
<table border=0>
<tr><td><dtml-let unitid="-1">
<dtml-tree id=unitid branches_expr="LookupChild(parent=unitid)">
<a href=&dtml-URL0;?exid=&dtml-unitid;><b><dtml-var name></b><dtml-var unitid></a>
</dtml-tree>
</dtml-let></td>
<td>
<dtml-if exid>
<dtml-let typelist="['','会社','事業所','部署','個人']">
<dtml-if child>
<table border=0><form method="post" action="UnitInsert">
<tr><td align=right>種別</td>
<td><input type=hidden name=type value="&dtml-child;"><dtml-var "typelist[_.int(child)]"></td></tr>
<tr><td align=right>親ID</td>
<td><input type=hidden name=parent size=7 value="&dtml-exid;"><dtml-var exid></td></tr>
<tr><td align=right>名前</td>
<td><input type=text name=name size=50></td></tr>
<tr><td align=right>郵便番号</td>
<td><input type=text name=postal size=8></td></tr>
<tr><td align=right>住所</td>
<td><input type=text name=address size=50></td></tr>
<tr><td align=right><input type=submit value="作成"></td>
<td><font color=red><b>入力しても作成ボタンを押すまでは更新されません!!</b></font></td></tr>
</form></table>
<dtml-else>
<dtml-let val="UnitSelect(unitid=exid)">
<table border=0><form method="post" action="UnitUpdate">
<tr><td align=right>識別ID</td>
<td><input type=hidden name=unitid value=<dtml-var "addQuote(p=val['unitid'])">><dtml-var "val['unitid']"></td></tr>
<tr><td align=right>種別</td>
<td><input type=hidden name=type value=<dtml-var "addQuote(p=val['type'])">><dtml-var "typelist[val['type']]"></td></tr>
<tr><td align=right>親ID</td>
<td><input type=text name=parent size=7 value=<dtml-var "addQuote(p=val['parent'])">></td></tr>
<tr><td align=right>名前</td>
<td><input type=text name=name size=50 value=<dtml-var "addQuote(p=val['name'])">></td></tr>
<tr><td align=right>郵便番号</td>
<td><input type=text name=postal size=8 value=<dtml-var "addQuote(p=val['postal'])">></td></tr>
<tr><td align=right>住所</td>
<td><input type=text name=address size=50 value=<dtml-var "addQuote(p=val['address'])">></td></tr>
<tr><td align=right><input type=submit value="更新"></td>
<td><font color=red><b>入力しても更新ボタンを押すまでは更新されません!!</b></font></td></tr>
<dtml-if "val['type'] < 4">
<tr><td colspan=2><a href=&dtml-URL0;?child=<dtml-var "1+_.int(val['type'])">&exid=<dtml-var "val['unitid']">>コドモを作る</a></td></tr>
</dtml-if>
</form></table>
</dtml-let>
</dtml-if>
</dtml-let>
</dtml-if></td></tr></table>
<dtml-var standard_html_footer>
重複多めで美しくないけどこんなもんかなぁ??? なんつっても 動いているしね