Python温泉一日目
タッチする自動ドアと、押すドア、引くドア、スライドするドアがあってひどい。
やば、酔ってきた。
二階建てデッキの下へ。
= uにauth.models.Userオブジェクトが入っているとして、 IPythonでprint u.firstnameってやるとエラーになるのはなぜだろうか。
= ダウンロード機能が付いた。 熱海に着いた。バッテリーがなくなった。 やるべきことをリストアップして優先順位をつけよう。
= ついた。
= 会議室はペットボトルの飲み物ならOK。
Mac率が高い、っていうか僕の机は僕以外Macだ。
= 静的略語展開について調べる。 略語展開。 メジャーモード内で登録できるらしい。django-modeで色々登録しよう。 動的展開がM-/なのに対して静的展開は C-x ' (expand-abbrev) で長い。 M-Spaceが「カーソル周囲のスペースをまとめて1個だけにする」 という謎なコマンドに割り当てられていたので これを付け替えることにしよう。
とりあえずdjango-mode内で適当なものを登録してM-x write-abbrev-file。 ファイルネームに何も入れずにEnter。 M-x edit-abbrevsで編集モードに。 あーー、"{ef"で"{% endfor %}"になるようにしようと思ったのに、 記号は略語に含まれないようだ。
とりあえず
(fundamental-mode-abbrev-table)
"eb" 1 "{% endblock %}"
"ei" 1 "{% endif %}"
"ef" 1 "{% endfor %}"
"el" 1 "{% else %}"
"sb" 1 "{% block %}"
"sf" 1 "{% for in %}"
"si" 1 "{% if %}"
"inc" 1 "{% include '' %}"
M-x abbrev-modeで略語展開モードにしたらウザイかなと思ったけど、 "ef "で"{% endfor %}"になり、 "def "では展開されない。便利だ。
追記:上みたいに空行開けちゃダメみたい。 そこで途切れるっぽい。 .abbrev_defsを直接編集する方が好みかも。
(define-abbrev-table 'fundamental-mode-abbrev-table '(
("ew" "{% endwith %}" nil 1)
("tr" "{% trans '' %}" nil 1)
("sw" "{% with as %}" nil 1)
("el" "{% else %}" nil 1)
("ei" "{% endif %}" nil 1)
("ef" "{% endfor %}" nil 2)
("si" "{% if %}" nil 1)
("eb" "{% endblock %}" nil 1)
("sf" "{% for in %}" nil 1)
("sb" "{% block %}" nil 1)
("inc" "{% include '' %}" nil 1)
))
write-abbrするとこんな風に適当な順番にされるから、
あくまで最初にちょっと作っておいてあとは自分でこれを書き換える。
もうwrite-abbrしない。
= authに入っているUserを拡張したい(例えば誕生日フィールドをつけるとか)場合、 最初継承してみて、うまくいかないので新しいUserProfileってモデルを作って FKでUserに張ってみた。
あとはそれに「unique=True」しておくのがいいらしい。なるほど。
= テンプレート期待と違う表示だと思ったら challengeって書くべきところがchallangeになってた。 なんかStrictモードっぽいのはないんだろうか。
= Django面白い。 蜘蛛の巣と同じで、 足がかりができてくると動き回るうちにだんだんしっかりしてくる。
= 一対多でコメントがレーティングをたくさんもつとき、 レーティングがコメントにFKする。 コメントは何も宣言しないが、rating_setができてる。
多対多の時は?
ManyToManyを宣言した側にフィールドの名前で普通に入っている。
{% for tag in comment.tags.values %}
{{ tag.caption }}
{% endfor %}
= {{ tag.caption }}を{{ tag.caption|escape }}にしておかないと、 HTMLタグが書かれたときに通ってしまう。 表示部分でレンダリングのたびにエスケープするんじゃなくて、 入力されたときにはがすべきか。 どうするんだろう。
= お腹空いた。
= ごちそうさま。
= Meadow、間違えて*.pycを開いたときに代わりに*.pyを開いてくれないかなぁ。
= .objects.all()[-6:]はできない。マイナスの値でスライシングできない。 まるでリストのように扱えてはいるけども、あくまでイテレータで、 遅延されたSQLクエリだから。
objects.order_by("-create_date")[:6]ってやった。 きっとSQLの中にordered by句を混ぜてくれているんだろう。
= ほうほう。joinとかはfor文に変な属性をつけることではなく、フィルタの形で実現されている。
フィルタの縦棒の前後にはスペースを入れると怒られる。
{{ tags|join:", " }}
複数のタグのANDで絞り込む機能ができた。
def tag_detail(request, tag_slugs):
slugs = tag_slugs.split("/")
tags = [get_object_or_404(models.Tag, slug=slug) for slug in slugs]
items = reduce(lambda x,y :x.filter(tags=y),
tags,
models.Comment.objects)
return render_to_response(
'doukaku/tag_detail.html',
dict(
tags=tags,
items=items))
こんだけ。URLが/tags/foo/bar/bazだとfooとbarとbazの絞り込み検索になります。
もちろん、存在しないタグを指定したら404。
Djangoすごー。
URLが正規表現でのマッチングだからこそできる技ですな。 自動的に/で刻んでしまうようなフレームワークでは面倒。
= んー。認証プログラムがSMTPを叩こうとして、失敗するなぁ。 自分のところでSMTPサーバが起動していることを期待しているのかな。 SMTPサーバーを自前で用意する。 XPでは元からSMTPサーバを持っているようだ。
= 自販機でお茶を買おうと思って外に出ようとしたら顔の赤いおじさんに「うちのじゃダメですか」と言われた。そして旅館内の自販機はお茶が180円だった。 外に普通に自販機があるような立地でそれはダメだろ。
= SMTPサーバを立てたらエラーメッセージが変わった。
= itermはC-Enterで最大化。 vimcolorは内部でvimを呼ぶ。
= SMTPをどう設定したらいいのかがよくわからない。 WindowsのIISでどうやってやるのか調べて解決しても、 サーバに入れたら動かなくなったりしそう。 でもアカウント作成ができないと投稿もできないしなぁ。
= http://www.red-bean.com/~bos/hgbook.pdf
= DjangoのデータベースAPIを使ったときに、 実際に発行されているSQLが何かを見る方法。
DEBUGがONなら
In [25]: from django import db
In [26]: db.connection.queries[-1]
Out[26]:
{'sql': u'SELECT "doukaku_challenge"."id","doukaku_challenge"."title","doukaku_c
hallenge"."body","doukaku_challenge"."create_date","doukaku_challenge"."comment_
count","doukaku_challenge"."code_count","doukaku_challenge"."tb_count" FROM "dou
kaku_challenge" WHERE ("doukaku_challenge"."id" = 1)',
'time': '0.016'}
こんなんなってる。
In [30]: models.Tag.objects.all()[::-1]
Out[30]: [<Tag: <em>hoge</em>>, <Tag: Foo>, <Tag: Hoge>]
In [31]: db.connection.queries[-1]
Out[31]:
{'sql': u'SELECT "doukaku_tag"."id","doukaku_tag"."caption","doukaku_tag"."slug"
FROM "doukaku_tag"',
'time': '0.000'}
= NXT Python おおお。LEGO MindStormがPythonで操作できる! MindStorm買います!
= Windows用のgettextの場所を露木さんに教えてもらった。 GetText for Windows。
= lxml。XPathが完全対応。全部Pyrexで書かれているので高速なんだってー。
Twisted Mind - 誰もさわらないlxmlについて。 ぼろぼろのHTMLでもパースできる。
= Meadow/Emacs memo: テキストの補完入力 ― abbrev ,定型句。 これを使うとEmacsの略語展開で展開した後のカーソルの位置とかを指定できる。
= _make-messages.py -l jaして、poを書き換えて、compile-messages.pyしても翻訳が反映されない場合、 サーバを再起動してみる。
= アカウント作成は メール送信に失敗するからここではデバッグできないや、 サーバ借りてからになるな、と思っていたけども、 話してみたら 「ローカルにメールサーバを立てて転送せずに内容だけ見たら。 メーラからリンクをクリックしなくてもURLだけコピペすればOK」 「って言うかメール送信する側のコードに手を加えられるんだからそこで表示してみたら」 ということであっさり解決。
= スタイルシートはよくわからない。 メインコンテンツとサイドメニューを80%、20%にしたときに、 サイドメニューが追いやられてしまうケースと 追いやられてしまわないケースの違いがよくわからない。
= 色々テストのせいでできたいらないユーザを消す。
In [50]: xs = django.contrib.auth.models.User.objects.filter(pk__gt=2) In [51]: xs Out[51]: [<User: hogehoge23>, <User: momo>, <User: momo2>, <User: momo3>, <User: taro>, <User: taro2>] In [52]: [x.delete() for x in xs] Out[52]: [None, None, None, None, None, None]やっぱ対話的っていいね。
追記:xs.delete()でいいそうです。
= 27時過ぎに会議室を抜け出してお風呂に入った。 24時間お風呂に入れる。 しょっぱい。海水っぽい。
体固い。
お風呂に入ったら体が温まって眠気が飛んだ。おなかすいた。
おお、4:44だ!
フィードバック
xs.delete() でクエリセット内の全オブジェクトを一気に消せるよ。