ラベル Django の投稿を表示しています。 すべての投稿を表示
ラベル Django の投稿を表示しています。 すべての投稿を表示

2009年12月11日金曜日

Django の Template Filter には任意の変数を使用することができる

公式ドキュメントに記載がなかったので、自分用メモ。

たとえばDjangoのフィルターで、
{{ some_value|floatformat:1 }}
としているところを、viewから変数を渡して
{{ some_value|floatformat:floatpoint }}
のように書くことができます。他にも
{{ now "%Y %m %d" }}
{{ now date_format }}
みたいに書くとか。・・・常識?

2009年9月3日木曜日

Python 2.5系列では__repr__()でunicodeを返すといろいろトラブルが起きる

Django(正確にはapp engine patch)のmanage.py shellで遊んでいるとき、とあるクラスを生成すると必ずUnicodeEncodeErrorが発生していることに気づきました。具体的には以下のような感じ。
>>> from game.models import *
>>> hts = HeroTemplate.all()
>>> ht = hts.fetch(1)[0]
>>> ht.template_name #問題なし
>>> ht.name          #問題なし
>>> hero = Hero(
... name=ht.name,
... symbol=ht.symbol,
... max_life=ht.max_life,
... life=ht.max_life,
... max_move=ht.max_move,
... move=ht.max_move,
... weapon=None,
... item=None,
... )
>>> hero             #ここでUnicodeEncodeError
>>> ht.createHero()  #上記と同じ処理をやるメソッド、これもUnicodeEncodeError
原因を調べていてわかったのですが、Python 2.5系列では__repr__()がunicodeを返すようにしてしまうとトラブルの元になってしまうようです。
参考にしたサイト:
http://d.hatena.ne.jp/alisue/20090402/1238690818

たとえば、
>>> class Abesi:
...   def __repr__(self):
...     return u'¥u3059¥u305a¥u304d¥u3044¥u3061¥u308d¥u30fc'
... 
>>> abesi = Abesi()
>>> abesi #UnicodeEncodeError
これを実行するとabesiを表示しようとしたタイミングでエラーになります。環境はWindowsXP上のCygwin 1.7 + Python 2.5.4で、ターミナル上ではshift_jisを使っています。始めっからターミナルがutf-8を扱えるような環境なら__repr__()でunicodeを返しても上手くいくかもしれません。
しかしながらどこの環境でも動くとはいいがたい状態なので、
  • __str__()と__repr__()はstrを返す
  • __unicode__()はunicodeを返す
Python 2.5系列ではこのルールを守っておいたほうが無難のようです。Python 3.0からはunicodeがデフォルトになるらしいのでこんな面倒ごとをいちいち考えなくてもよいのでしょうか?いまだにPython 3.0試していませんが、ちょっと興味が湧いてきました。


■っていうかそもそも
Djangoのdjango.db.models.Modelクラスは特にオーバーライドしなくても綺麗な__repr__()を出力してくれるので、デフォルトの__repr__()を使えばよかった><

2009年4月26日日曜日

MacPortsを使って、Pythonの開発環境を整えてみた

ここ最近勉強会続きだったため、複数のバージョンのPythonの開発環境の整備をする必要に迫られました。
まずはPython2.6.2をインストールしようと考えたのですが、python.orgからdmgでダウンロードしてインストールすると余計な物をたくさんインストールされてしまいますし、何より環境の切り替えが大変です。
(Mac付属の2.5.1でないとDjangoがエラーを吐いたりするため、いつでも2.5.1に切り戻せるようにしたい)

そこで今回はMacPortsを使って開発環境を整えてみました。

■Pythonのインストール
これはMacPortsから以下のコマンドを実行するだけでいけました。
sudo port install python26

ただ、依存するモジュールが非常に多いためビルドに大変時間がかかりました。MacBook Airで、およそ1時間ぐらい。
これで/opt/local/Library/Frameworks以下にPython.frameworkがインストールされるのですが、インストールしただけでは自由に元々存在するPython 2.5.1との切り替えができません。
そこで、同じくMacPortsで提供されている、python_selectというスクリプトをインストールします。
sudo port install python_select

インストールしたら、以下のようにして自由にPythonのバージョンを切り替えることが出来ます。
$ python_select -l #利用可能なバージョン一覧を表示
Available versions:
current none python25-apple python26
$ python_select python26 #python2.6に切り替え

こいつは大変便利です。

■Djangoのインストール
DjangoもMacPortからインストールできます。
sudo port install py26-django

Djangoだけではなく、jinjaやSQLAlchemy, Werkzeugなど、名前の知られているPythonのフレームワークはすべて存在しているようです。とっても楽ちん。
ちなみにインストールできるportとしてpy25-djangoのようにPythonのバージョンを指定しているものと、py-djangoのように指定していないものがありますが、py-djangoをインストールしようとすると突然Python2.4をインストールしようとしやがりましたので、基本的にはPythonのバージョンを指定しているportを選んだ方が良さそうです。

さて、MacPortでインストールしたPythonのためにDjangoをインストールするのは簡単でしたが、
問題になってくるのは元々標準で入っているPython2.5.1のためにDjangoをインストールするときです。
easy_installが使えるようなので、今回はeasy_installを使ってインストールしました。
sudo easy_install django

ただしportと比較すると後からアンインストールするのが面倒だという欠点があります。portが使えるならportがいいですね。

■PILのインストール
PILのインストールも基本はMacPortで。
sudo port install py26-pil

問題はPython 2.5.1にインストールするときです。私の環境では、easy_installが失敗してしまい簡単にインストールできませんでした。
悩んだあげく、PILのウェブページからPython Imaging Library 1.1.6 Source Kitをダウンロードし、直接setup.pyを実行して解決しました。
tar zxvf Imaging-1.1.6.tar.gz
cd Imaging-1.1.6
sudo python setup.py install