2009/06/27

jquery option uncheck

jQuery にお友達になって欲しいと思ってはいるんですが中々難しく

何したかったかっていうと Django の吐く form で
とある field でとある項目選んだら他の field がビョコっと現れるっていう
で、form.as_table とかだと tr/th/td には何の attribute も振られてなくて
どないして選択せいっちゅうねんと思ったんでリファレンス一生懸命読みまして
Traversing/closest - jQuery JavaScript Library
closest って函数が直近の entity 捜してくれるってんでターゲットは確定

bind で event に対して函数が割りあてれるのは理解してたので
select の場合は select かと思ってたら click だっていうのに試行錯誤したけど
event と函数の bind も OK

隠したり出したりってのは CSS で visibility とか display とかいじればいいのかと思い
display で none と inline でと思ったら table が崩れてしまう
inline じゃなくって table 関係のものを指定してやらなきゃいけなかったみたいなんだけど
ぼーっとリファレンス見てたら hide って見付けて show も見付けて
show なんてちゃんと文脈読んでくれて感動したりして
つか、もしかして display 属性消して default に戻してるだけなのかな??

で、select で選択外したときには出てきた入力項目空にした方がいいんじゃないかと思い
radio はどうやって外すのよ! っていうとググった結果
jQuery: Check / uncheck form checkbox and radio
.removeAttr("checked")
こんなんで OK
普通の text field は
.attr("value", "")
ってしてみた

で、できたのが
$(function() {
$("[for*=_opt]").closest("tr").hide()
if ($("[id^=id_foo_opt_]").attr("checked")) {
$("[for*=foo_opt]").closest("tr").show();
}
if ($("#id_bar_opt").attr("value")) {
$("#id_bar_opt").closest("tr").show();
}

$("option[value=foo]").bind("click",
function () {
$("[for*=foo_opt]").closest("tr").show();
}
)
$("#id_abc > *").not("[value=foo]").bind("click",
function () {
$("[for*=foo_opt]").closest("tr").hide();
$("[id^=id_foo_opt_]").removeAttr("checked");
}
)

$("#id_bar > option").filter("[value=2]").bind("click",
function () {
$("#id_bar_opt").closest("tr").show();
}
)
$("#id_bar > option").not("[value=2]").bind("click",
function () {
$("#id_bar_opt").closest("tr").hide();
$("#id_bar_opt").attr("value", "");
}
)
})
こんなんなんだけど、HTML の方が無いと何が何だか分からないかしら
<tr><th><label for="id_abc">FOO:</label></th><td><select name="abc" id="id_abc">
<option value="" selected="selected">---------</option>
<option value="new">新</option>
<option value="old">旧</option>
<option value="foo">他</option>
</select></td></tr>

<tr><th><label for="id_foo_opt_0">他って:</label></th><td><ul>
<li><label for="id_foo_opt_0"><input type="radio" id="id_foo_opt_0" value="xxx" name="foo_opt" /> xxx</label></li>
<li><label for="id_foo_opt_1"><input type="radio" id="id_foo_opt_1" value="yyy" name="foo_opt" /> yyy</label></li>
<li><label for="id_foo_opt_2"><input type="radio" id="id_foo_opt_2" value="zzz" name="foo_opt" /> zzz</label></li>
</ul></td></tr>


<tr><th><label for="id_bar">BAR:</label></th><td><select name="bar" id="id_bar">
<option value="" selected="selected">---------</option>
<option value="0">要</option>
<option value="1">不要</option>
<option value="2">済</option>
</select></td></tr>

<tr><th><label for="id_bar_opt">済んだのは:</label></th><td><input id="id_bar_opt" type="text" name="bar_opt" maxlength="10" /></td></tr>
こんな感じ

Django は input とかに label を付けてるからその label の for 捜して
_opt で終わってたらとりあえず隠しちゃって
でも何か値が入ってるようだったらやっぱ見せるようにしています
あぁ、別に text とか radio で個別にやらなくても
とにかく _opt なものに片っ端からやってもいいのか
text が checked かどうか調べてもきっとスルーしてくれるよね!

value が foo の option が選ばれたら、対応する _opt の直近の tr を show
それ以外の option が選ばれたら hide して check を外す
id_foo_opt-* は radio なのです
何か、show のときの selector が唐突だなぁ

で、似たことを bar で id_bar_opt が text の場合にやってます

何かもっと沢山ググってるんだけど、まとめるの面倒
  1. jquery firebug
  2. django form jquery
  3. django jquery _html_output
  4. selector jquery
  5. jquery parent
  6. jquery select option
  7. jquery select option bind
  8. jquery select 選択されたら
  9. jquery 選択解除
  10. jquery 選択解除 select
  11. jquery hide
  12. jquery select option unselect
  13. jquery select checked
  14. jquery option uncheck
  15. jquery value remove
今日 jquery 入ってるので少なくともこんだけググりました
教訓はいつもと同じ
「ドキュメント・リファレンスを読もう」

2009/06/26

jquery ワイルドカード

jQuery で少しだけ何かしようと思ったんですが
そもそも entity の選択の仕方が良く分かってないなと思い
こういうのは正規表現とかでバリバリ指定できないもんなのかと
とりあえずワイルドカードくらいは使えたらいいなということで
ググりました

jQueryでのワイルドカードSelector - プログラマ的京都生活
いやん、その名もずばりなタイトル! って思ったんですが
リファレンスをちゃんと読め、という話ですねw
ごめんなさい、ごめんなさい

というわけで、jQuery と selector という正しい検索語を手に入れ
API/1.3/Selectors - jQuery JavaScript Library
わざわざ Google 使うなと
上で紹介されてた [] で括るのは Attribute Filters ってやつだったんですね
前方/後方/どこでもサーチができるみたいなんで
これで色々検索できました

あとは、id とか class のネーミングセンス、か?

2009/06/25

sql order

SQLAlchemy で Query を sort したかったら order_by って method があるので
どんなキーで sort するか指定してやったら終わりです、複数もいけるよ

でもね、昇順で sort したいと思った瞬間にもぉ分からなくなってしまったんです
order とか order_by とか reverse とかでドキュメントを検索しても良く分からないし
上の単語からめてググっても分からないし

で、ドキュメントつらつら眺めてたら SQL 文とかも書けるよ! って書いてあって
そもそも SQL のときどうするの? と思って検索しました
レコードの並び替え - ORDER BY句 : SQL入門講座
あぁ、なるほど、ORDER BY で DESC とか ASC とかで指定するのね

で、はっ! っと思ってドキュメントで ASC で検索してですね
SQL Statements and Expressions — SQLAlchemy 0.5.5 Documentation にですね
sqlalchemy.sql.expression.asc(column)

Return an ascending ORDER BY clause element.

e.g.:

order_by = [asc(table1.mycol)]
ちゃんと書いてある
アイヤー、ミノカシテタアルカ、ワタシ
つわけで、できました、降順も、良かった

paginate_by

やっぱ色々手を抜けたらいいなと思いまして、generic view 素敵に違いないと信じつつ
沢山のデータが出てくるときも「次へ」とかクリックできる仕組み、あったらいいな
で〜、Django で何だっけそれって思って昔写経したの見たら paginate_by と書いてあり
よーし、と思ってとりあえずググりました

しかし、検索語が悪いようで最初の方は心ときめくもんが出てきません
9 位が 2007-01-25 - SumiTomohikoの日記
とりあえずここに書いてあることがあれば私には十分でした
でも、ドキュメントの和訳が 1 ページ目に出ないとはまだまだだぞ Google
14 位に出てはきたんだけど
http://djangoproject.jp/doc/ja/1.0/_sources/ref/generic-views.txt
こっち出すの? そうなの?

で、まぁ paginate はできるようになりました

でもね、いま SQLAlchemy 使ってるの
これでも paginate できるのかしら?
で、ググ、らなかったんですね、今度は、ソース見てみました

django.views.generic.list_detail.object_list は
queryset って名前で model から作った query 引き受けるんですが
そしたら Paginator とやらに渡してるから今度は django.core.paginator.Paginator
眺めると、とりあえず slice できれば良さそうだったんで SQLAlchemy でもいいかな?
って思って SQLAlchemy の Query 突っ込んだら、怒られました
'Query' object has no attribute 'model'
おぉ
template の名前作るのに model の名前を使ってるらしい
けど template は object_list で指定してやればいいので
object_list(request, queryset, template_name='app/list.html')
的なことをしてやり
動いちゃいました

3 日後くらいには「やっぱ generic view 死ね」とか言ってるかもしれませんが
とりあえず動いたんで良かった
Pylons とか夢想しただけで済んで良かった
Python には Query のガイドラインとかもあるんだろうか?

2009/06/24

"unexpected EOF on client connection" sqlalchemy

SQLAlchemy 使ってみてますが繋いでる先は PostgreSQL です
なぜか身の回りは PostgreSQL なのです
PostgreSQL徹底入門片手に奮闘の毎日です

ログを見てみたら "unexpected EOF on client connection" って言われてます
で、どうも、ipython から使ってると起きてるみたい
気持ち悪い
調べました

まぁ、似たようなこと思う方も沢山いらっしゃるようでして
[sqlalchemy] shutdown database connection - Denis Shaposhnikov - com.googlegroups.sqlalchemy - MarkMail
1 行ですよ、瞬殺ですよ

engine に dispose させろってことだそうです
なるほどー

2009/06/22

django "disabled" form

form で、いじらせたくないけど見せたい項目があると
input で disabled とか input とか指定するかと思います
小粋空間: input 要素の disabled 属性と readonly 属性の違い
なるほど、こんな違いがあったとは

Django でも Model で editable=False ってのができるんですが
created_at とか modified_at のようにサーバ側で勝手に保存しとくんで
「ユーザーには見せないし設定させないよ」っていう趣きです
でー、admin にも出なくなったりして、出すのにまた一つ手間が増えるし
ユーザーに見せるのにもうひと手間掛けないとだし

でー、ググってみたら
(何で "disabled" かというと、"" で括らないと disable とかも hit しちゃうからダヨ!!)
In a django form, How to make a field readonly (or disabled) so that it cannot be edited? - Stack Overflow
ModelForm の __init__ を override して実現してらっしゃいました
つか、えっと、指定した Field の widget の attribute を変えてらっしゃるんですが
これは form に readonly とか付けるだけなんで Model の save も override しろとのこと

あとは、用途によって色々使い分けたらいいかなぁ〜、っつう感じでした

"generic view" "verbose_name"

generic view が大好きさぁ〜
ってことは全然ないんですが済むなら済ましたいと思ってました

Model のインスタンスの詳細を表示するには django.views.generic.list_detail.object_detail 使います
object_detail は template に Model の instance を object という名前で渡します
そう、Model の instance だけ渡ってしまうのです、困りました
例えば
name = models.CharField(u'お名前', max_length=256)
なんてしてた場合
「お名前」にアクセスする方法が無いのです
でも template に「お名前」とか書き込むの嫌だしなぁ〜

でー、ググって出てきたページがこちら
とりあえず、な generic view の object_list の拡張 - muddy brown thang
            (以前略)
def render(self, name):
field_verbose_name = gettext(
self._queryset.model._meta.get_field(name).verbose_name)
(以下略)
まじっすか、_meta っすか

なんか、generic view で code の数減らそうとか言っといて
結局そんなもん持ち出さにゃいかんというのは何か辛くない?
そう思って先生にご相談申し上げてみたところ
「自分の設計をまず疑った方がいいっすよ」
「フォームを使わないのに使おうとしてる時点でおかしい」
「つかコード呼んでくださいよw」
「ipython で ?? を憶えてください。」
というあたたかいお言葉を沢山頂いたので不貞寝しました

つわけで _meta は 1 つの正解だったということみたいなんですが
form 使えばいいらしいということも聴いたので少し調べると
Model の instance は __dict__ って持っていて
まぁ幸い ModelForm は用意してたので dict を食わせてやったら
できた form の fields の中の field の label とかでも何とかなりました
    object_dict = object.__dict__
form = PersonForm(object_dict)
fields = [ {'label':y.label, 'value':object_dict[x]}
for (x, y) in form.fields.items()]
こんな感じ

ん〜、何か、間違っちゃないかしら、これでいいのかしら

2009/06/21

autoload sqlalchemy cache

検索語と得られた知識が異るというのは良くあることですが

autoload はスババーと table 拾ってくれて何もしなくて楽チンなのですが
試してて ipython とかで file 読んだりする度に全部 table 取ってきます
まぁ、そらぁ拾ってこないと分からないんだから仕方ないし何か無駄だなぁと

で、ぐだぐだ言ってたら「cache する仕組みとかあるはずだからググれば」と
よーし父さん、と思ってとりあえず cache って入れて検索したら top に来たのが
Jonathan Ellis's Programming Blog - Spyced: Why SQLAlchemy impresses me
何やら comment 欄で cache という単語が出てきていて
Session の cache がどうとかいうことで、そうか Session が色々持ってるのかも?
という今のところ想像

で、そうじゃなくて、本文の方で
users = Table('users', metadata, autoload=True)
orders = Table('orders', metadata, autoload=True)

class User(object): pass
class Order(object): pass

mapper(User, users,
properties={
'orders':relation(mapper(Order, orders), order_by=orders.c.id),
})
ってしてはって、
あぁ、sqlalchemy.ext.declarative.declarative_base 使わなくっても十分短いし
explicit でいいのかなぁと「ハッ!」っとさせられました

でも、既存 db でなくって普通に使おうって場合は explicit ばっかじゃ疲れちゃうかなぁ
まつもとゆきひろさんも Matzにっき(2007-09-05)
それがPython的ってもんなのかねぇ
と言うてはる
Ctrl-1 とかしたこと無いしなぁ

脱線し始めたからついでに
Pylons / SQLAlchemy のチートシート集もちょっと素敵か
Pylons って Google App Engine のアカウントが取れて何か試そうと思ったときに
Django とか何かそんなの試せないのかしらついでにと思って調べてできそうで
でも Pylons のこと良く知らなかったから避けたのよね、結局 Django に。
や、そのときが Djang っぽいもの触るのも始めてだったんだけど。

閑話休題
from sqlalchemy import create_engine, Table, MetaData             
from sqlalchemy.orm import sessionmaker, relation, backref, mapper

url = 'mysql://username:password@server/db_name'
engine = create_engine(url, echo=True)
metadata = MetaData(bind=engine)

parent = Table('parent_tb', metadata, autoload=True)
child = Table('child_tb', metadata, autoload=True)

class Parent(object):
pass

class Child(object):
pass

mapper(Parent, parent,
properties={'children':relation(mapper(Child, child),
backref='parent')})


Session = sessionmaker(bind=engine)
session = Session()
こんな書き方もできまっせー、ということで
何となく DataMapper してる雰囲気を感じませんか?
あ、感じませんか、そうですか、そうですか