2009年12月10日木曜日

Django snippet 妙なところで嵌った

 models.py に新しい項目を追加して、データを登録、きちんと表示できることを確認して一安心したら、そのデータの管理画面が開けなくなった。

 エラーは
TemplateSyntaxError at /admin/itempage/item/8/

Caught an exception while rendering: 'FieldFile' object is unsubscriptable
 unsubscriptable ってどう意味と調べていくと、「コンテナ型ではない」ということらしい。

 その下には
Template error

In template c:\python262\lib\site-packages\django\contrib\admin\templates\admin\includes\fieldset.html, error at line 12
と表示されている。テンプレートの問題?いや、これは django のテンプレートだから直接関係ない。そうすると自分で書いたテンプレートの問題?とはいっても、admin の画面でエラーが出るわけだから自分で書いたテンプレートは関係ない。そうすると admin 用の class の定義?
 確かに今回定義を追加した。しかし、データ登録前は正常に表示されたのだが...。今回追加した定義をひとつずつ外していくと...、RemovableFileField がトラぶっているらしい。
 RemovableFileField は djangosnippets からもらってきたものなので確かに怪しいが、同じソースの RemovableImageField は全く問題なく使えている。

 はて?

 2時間ほどあっちこっち追っかけて全くわからない。FieldFile を見つけられなかった。一旦やめて一晩考える。仕切りなおして RemovableFileField のソースをじっくり眺めてみた。
 関係ありそうなところで RemovableFileField と RemovableImageField で違っているのは
            if self.is_image:
s += u'<BR><img src="http://www.blogger.com/%s/%s" width="100" />' % (settings.MEDIA_URL, value)
else:
s += u'<BR><a href="http://www.blogger.com/%s/%s">%s</a>' % (settings.MEDIA_URL, value, os.path.basename(value))
 RemovableFileField が実行するのは下の行。この行にブレークポイントを調べていくと...、value の「型」が FieldFile !。os.path.basename は 'return split(p)[1]'。ということは、FieldFile の返す文字列は str/unicode じゃないから split() がエラーになっているということ?
 os.path.basename(value) を os.path.basename(unicode(value)) に変更したらキチンと動くようになりました。

 たぶん python のバージョンが上がって動きが微妙に変わってしまったのだろう。

 解決するのに都合3時間ほどかかりました。Django がブラウザに表示するエラーはとんでもないところを指すことがあることがわかりました。

 これを djangosnippets に報告したいが...、挑戦してみよう。...と思って djangosnippets のコメント欄を良く見たら、すでに同じ内容が投稿済み orz。このコメントは一回読んだはずなのに....。

0 件のコメント:

コメントを投稿