2009年11月30日月曜日

Django 次のステップへ

 とりあえず某 HP がそれなりにコピーできたので、目玉の条件検索機能を追加すべく新たに色々色々と調べにかかる。

 [条件検索]のボタンを押すと、新たに一枚ブラウザを開き、その中に選択肢を並べ、チェックボックスで選んでもらって検索、という形にしたい。
 手元にある参考書に似たような機能はあるのだが、これが Django の 0.96 用で、使っているメソッドが 1.0 ではバッサリ落ちている。

 一応、「アプリケーションを Django 0.96 から 1.0 に移行する」というページがあって、「newforms の代わりに django.forms を使う」の中に書かれているoldforms というのを使っているのだが、「古いフォームシステム (以前は django.forms と呼ばれていた django.oldforms)を使っているのなら、フォームを書き直す必要があります。まずは forms のドキュメント を読むところから始めてください。」ですと orz

 きちんとお勉強するか、代替方法をネットで探すか、いや、サンプルソースのありそうな本を探すか。

Django MVC ってのは、

 今の作業で大まかなところが落ち着いてきて表示部分の細かいところをやっているのだが、MVC ってのは、ソースがバラバラといろんなところに散らばるだけのような気がしてきた。

 テンプレートに for と if を放り込んで条件分岐させ、それでも足りなければフィルター・タグを作る。汎用 view を使うためには更にコードが散る。

 んー、かえってメンテナンス性が落ちないか?

 なにか根本的なところでオイラが間違っている気もしないでもないが...。

2009年11月28日土曜日

python+SQlite データ移行プログラムで嵌る

Django 側で None のデータの扱いに問題があった。一時間以上嵌る。

 NoneType というのは覚えておこう。

2009年11月27日金曜日

Django+sqlite PositiveIntegerField は

 blank=True と設定したら、admin の画面から save 出来なくなった。どうやら null=True も同時に設定しないとだめなのか?

 他の数値系の型もたぶん同じ?

Django Invalid block tag っていうエラーが出た

 原因は....、

 {% endi %]
^^^

 というのがいくつか(^^;入っていたため。

 これで tag のネストが狂ったらしい。

2009年11月23日月曜日

python オブジェクトのコピーって

 いちいち copy とか deepcopy とかの関数を呼び出してやらなくちゃならないのね。

 C++ なら 'A = B' で、オブジェクトそのものをコピーするのだが、Python だとポインタのコピーにしかならない。

 少々嵌った。

 関数の引数も全部参照渡しだそうだ。C++ のときは暗黙の参照渡しのプロトタイプは禁止してたのに、python では default か。

 トラップでいっぱいだ。

2009年11月22日日曜日

Django save する前に pk(id)を得る方法

 db.models.base.py のsave() メソッドあたりのコードを読んでみたが、ナニを書いているのかさっぱりわからなかったので、変数というかオブジェクトというかをデータベースに登録して管理というか、自前で計算することにした。

 models.py にこんな感じで追加
class LastId(models.Model):
lId = models.PositiveSmallIntegerField()
def get_id(self):
return self.lId

def inc_id(self):
self.lId = self.lId + 1
self.save()

def set_id(self,value):
self.lId = value
try:
lasId = LastId.objects.get(pk=1)
except:
lasId = LastId()
lasId.set_id(0)
lasId.id = 1
lasId.save()

class Item(models.Model):
def getId(self,name):
if self.id is None:
self.id = lasId.get_id() + 1
return u'cars/%s/%s' % (self.id,name)
...
def save(self, force_insert=False, force_update=False):
if lasId.get_id() + 1 == self.id:
lasId.inc_id()
super(Item,self).save(force_insert, force_update)
 難点は、manage.py syncdb を実行するときに try: ... lasId.save() をコメントアウトしないとエラーになること。インスタンス生成部分を別ソースに移動したりと色々やってみたが回避できない。from の循環参照を回避できればなんとかなりそうだったので C/C++ のようにプリプロセッサのマクロとかあればなんとかなりそうなんだが。
 該当箇所をコメントアウト -> syncdb を実行 -> コメントアウトを外す、とひと手間かかる。サーバーにインストールするときは、sqlite のデータベースも一緒にコピーする必要がある。

 「エレガントな解法」がありそうな気はするのだが...。

2009年11月21日土曜日

aptana + subversion 使い方がわからない

 古いソースが見たくなって update to revison をしたら、当のソースに古いソースと差分が (diff の出力みたいな感じで)混じってしまった。

 こんなこともあろうかと、あらかじめバックアップしてあったソースと差し替えると、今度は conflict してコミットできない。

 結局 synchronize の画面でそのファイルを右クリック -> Mark as Marged を選択してコミットできるようになった。

 なにがなんだかさっぱりわからない。

 この壁を越えないと subversion を使う御利益は出ないのだろうが、高そうな壁だ。

2009年11月20日金曜日

Django 大ポカ

  class Foo(models.Model)
__unicode__(self):
return {int の変数}


 としたばっかりに、このクラスを管理画面から更新・追加するときに

coercing to Unicode: need string or buffer, int found

 なるエラーがでて2時間ほど時間をドブに捨ててしまった...orz

----
 て、わかってからエラーメッセージ + Django を丸々 google 様に食わせたら一発で答えが出てきた orz。

2009年11月19日木曜日

Django+python pk が db に書き込ま前に必要なんだ!

 db に書き込む前のインスタンスの pk を知る必要が出てきたので、悪戦苦闘

 最新の pk を記憶する専用のクラス・インスタンを作って管理しようとしているのだが、なんとかうまくいきそう、なんだが疲れたので時間切れ。

 余分なところで時間がかかる。

---
 あと、unbound method save() must be called with LastId instance as first argument (got nothing instead) 系のエラーで嵌った。
 オイラの場合はリンクの循環というのではなく、f = Foo() と書くべきところを f = foo と書いて f.save() とやってしまったこと。インスタンスではなく、クラスのメソッドを呼び出そうとしたという意味か?

2009年11月18日水曜日

aptana subversion を使えるようにした

 今までは統合環境を使わず、ソースをいじるのも一人だったのでバージョン管理システムなど使わず、適当なタイミングでディレクトリ全体を lha でアーカイブしていたのだが、django で開発していると異様にファイルの種類が増える(python のソース、テンプレート、画像ファイル、データベースファイル)のと、eclipse が subversion のクライアントをサポートしているので、使ってみることにした。

 クライアントのインストールは aptana(2.0.0.1256072654) の Help->Install New Software を選択し、開いたダイアログの Work with は All Available Site を選択、Name は Collaboration から Subversive SVN 関連の二つを選択してインストール。


----
 次は subversion のインストール。使ったのは VISUALSVN SERVER。一発インストールで apache までインストールしてくれるそうな。便利な世の中になったもんだ。
 ちなみに、subversion の URL は、管理画面のツリーの一番上を開くと出てくる。


----
 続いては、既存のプロジェクトを subversion のリポジットに登録すること。既存のプロジェクトは登録できないと思い込み、既存のプロジェクトをコピーして新しいプロジェクトを作ろうとしたがうまくいかず。
 調べてみると、プロジェクトの親ホルダーの上で右クリックして team->share project を選択すればよいことがわかる

----
 手順をこのブログにまとめるところまでで2時間半。果たして、元は取れるか??

2009年11月17日火曜日

aptana リストア

 テストプロジェクト中のデータディレクトリを削除するつもりで、メインプロジェクトを削除してしまった (; ;)

 バックアップを引っ張り出して色々やってたら、プロジェクトとしての登録が消えただけで、プロジェクトファイル一式は丸々残っていた。

 これをインポートすれば良いだけの話だったのだが....。

 ためしに、最初にディレクトリ名を変えてリストアしたソースをインポートしようとしたら、aptana がハングアップ。aptana を再起動したらプロジェクトが復旧していたがなぜか動かない。
 調べていくと、結局プロジェクトの復旧がうまくいっていなかったようだ。

 もともとあったディレクトリをインポートして解決。

 こんなことに一時間ほどかかってしまった。やっぱり統合環境は嵌ると時間を食う。

2009年11月16日月曜日

Django+python pk は db に書き込まなくてもわかった

 色々やっているうちに、aptana の Variable window を見ていると、目的のインスタンを :と表示している。

 もしやと思って str(<インスタン>) とすると、 id(pk) を返してくる。db 書き込み前でも。
 インスタンスを評価すると id(pk)を返してくるとは。Django 恐るべし、いや python 恐るべし?単に def __unicode__ で self.name を返していて、インスタンの name に 1,2,3... と入れているだけだった。orz

 どうしよう?

Django+python pk は db に書き込むまでわからない

 インスタンスの画像データを pk を含むディレクトリに入れようとしたら、動かない。この間は出来たのにと思い調べると、
・修正のときは動く
・新規登録のときは動かない
ことが判明。db に登録前は pk が無効ということが判明 orz。

 じゃあ自前の変数に pk のコピーを持とうかと思ってコンストラクタをオーバライドしたら動きが変。
 調べていくと、オーバーライドしたコンストラクタが、もとのコンストラクタを、引数を全部準備して呼び出さなくはならないことが判明。
 引数が合わなくてもエラーもワーニングも出さないんだもん、python って。いや、MT のライブラリのバージョンが合わないときもこれで嵌ったから ll 全般の傾向か。
 メソッドをオーバーライドするときは親のクラスの元のメソッドを調べなくてはならないことが判明。これって C++ では当たり前だったっけ?少なくとも引数の型が合わないとエラーになったはず。
 こういう不具合の種をまかないために型チェックが厳しくなったはずなのに...。

 import している models の場所がわからなくて結構探した。おいらの環境では C:\Python262\Lib\site-packages\django あたりにあるらしい。

2009年11月14日土曜日

Django ImageField をいじる

 ImageField をこちらの delete box 付きに変更し、ファイル名入力のヨコに小さなイメージを付け、イメージファイルの保存ディレクトリにインスタンスの ID をつける。

----
 気が付けば中三日も休んでしまった orz。

2009年11月9日月曜日

Django Item 削除時の画像削除

 デストラクターをオーバーライドして一発でした。なまってるなぁ。

 けど親クラスのメソッドをオーバーライドしたとき、親クラスのメソッドを自前で呼び出さなくてはならないとは。
 あと、self の扱いが面倒だ。C++ の this はデフォで書かなくて済むんだけどなぁ...。

 あと、なんだか動作が不安定に。フレームワークとデータベースエンジンを使う意味が....

 

Django 管理画面のリストに画像を追加


 管理画面から Item を削除するとき、画像も一緒に削除できないかと探していたら、こんなページを発見

 管理画面の一覧に画像を表示することもやりたいことのひとつだったので、さっそく挑戦。

 なんだかんだと2時間近くかかって実装。
    def thumb(self):
tinythumb = unicode(self.photo11).replace('\\','/').split('/')
tinythumb[-1] = 'tiny/'+tinythumb[-1]
tinythumb = '/'.join(tinythumb)
if not os.path.exists(settings.MEDIA_ROOT+tinythumb):
im = Image.open(settings.MEDIA_ROOT+unicode(self.photo11))
im.thumbnail(TINY_SIZE,Image.ANTIALIAS)
im.save(settings.MEDIA_ROOT+tinythumb,"JPEG")
return """tiny thumbnail image"""%(settings.MEDIA_URL,unicode(self.photo11),settings.MEDIA_URL,tinythumb)
thumb.allow_tags = True
thumb.short_description = 'XXXX'

 元が 0.96 用だったせいもあってだいぶ嵌った
・オリジナルは models.ImageField を単なる文字列として扱っているが、unicode()で括ってやらないと文字列操作のメソッドが使えない
・Image.save() で書き込むときは、ディレクトリがないとだめ。models.ImageField のときは勝手に作ってくれたのに...
・html に吐き出す url の文字列でだいぶ悩む。結局もとの media を site_media に変更。URL の root からアプリケーションを動かして嵌ったのは2度目。そろそろ覚えんと。

aptana のデバッグ機能がなければ、今回は歯が立たなかったかも。

todo:画像の削除

 管理画面で Item に登録した画像を Item 削除時に削除すること。

2009年11月7日土曜日

Django 新規プロジェクト作成で嵌る

 画像の扱いを調べるために小一時間はまってしまった。0.96 ベースの本とうろ覚えの知識、動いているソースを元にしたのが原因か?最初からチュートリアルを見ればよかった。

 今回引っかかったところ。

1.python django-admin.py startproject が動かない。調べてみると django-admin のスペルミス orz

2.追加した model が管理画面に表示されない。INSTALLED_APPS にアプリを追加していなかった。

3.起動途中でエラー。models.py の先頭行に # -*- coding: utf-8 -*- をいれずに漢字を使っていた。実行するとコンソールにエラーが何行も出てくる。

4.models に追加した XXXAdmin が、なぜか admin.py から見つからず(XXX のクラスは認識していた)。ファイルを書いたり消したり、文字列を削除したり直したりしているうちに動いた。原因不明。

Django ひっかかった

 class のメンバに BooleanField を追加して、初期値を True にすることにした。

 最初に、コンストラクタの __init__ を使って初期化しようとすると、管理画面で一覧が出なくなってしまった。

 深追いはやめて、BooleanField で検索をかけるとこういうページが出てきた。初期値の設定は initial ね。initial=True と書くと...、エラーになる。もしかして 'inital=True' と書くと...、動いた。けど、初期値が True にならない。他のメンバを見ると...、シングルクオーテションで括っていない。よくよく見ると... forms.Form って?

 初期化したかったのは models.Modelの BooleanField、ドキュメントを見ていたのは forms.Formの BooleanField
 クラス名は同じようなというか、同じのがたくさん並んでいるのにオプションが違う。

 結局 default=True で目的は果たす。もちろんシングルクオーテションでの括りはなし。

 紛らわしい。

2009年11月6日金曜日

aptana うそでしょう?

 サイトのデザインをいじっているうちに、<table> で作ったタグがまともに表示されなくなる。<table>の中のタグがレンダリングされずに、テーブル配置後の文字列だけが html にレンダリングされていたり。
 色々いじくり回してもだんだんおかしくなるばかりなので、新しい表を作って色々やっていくと...。

 aptana の HTML エディターでは、表示から半角の空白と全角の空白を判別できない !!

 少なくともオイラの(たぶん)デフォルト設定で UTF-8 の .html のファイルはそおなっている。

 これは嵌る、要注意だ。

aptana HTML ファイルを編集しようとしたら

 Django の template を編集しようと .html のファイルをひらいたら、激しく文字化け。
 エディターのプロパティーを開いてもエンコーディングらしき項目はなし。

 困ったときの google 頼み、'eclpse html 文字コード'でこんなページを見つけた。ファイル毎にコード属性が付くわけね。

2009年11月5日木曜日

python+SQlite データ移行プログラムで嵌る

 先日作ったデータ移行プログラム、テーブルが増える分には動いていたが、テーブル内の item が増えると動かない。ロジックに問題があったのと、NULL 不可に引っかかって遊ばれる。

 ほぼ半日かかってしまった。

 昨日今日と、こんなのばっかり。

2009年11月4日水曜日

Django どうでもいいところで嵌る

 管理画面をあれこれしている中、一覧の表示に ManyToManyField を出したくなった。

 こちらのページを参考にしてコードを変更したら表示された、んだけど日本語が unicode のコード表示([u'\u5036\u77e5\u5b89\u753a\u82b1\u5712'])。

 これは、データー変換プログラムで悩んだから大丈夫だろうとあれこれやっていくが...、うまくいかない。

 結局コード変換の問題というより、戻り値がリストだったことが原因だった模様
def selected_tags(self):
'''return selected tags'''
tag_titles = []
for tag_obj in self.tags.all():
tag_titles.append(tag_obj.title)
return tag_titles
 の最後の行を
return tag_titles[0]
にしたら正常に日本語が表示された。

----
 aptana 、さっそく役にたった。

 

Django 管理画面を変えるのに嵌る

 0.96 -> 1.0 でちょっとしたというか、大きなというか、互換性のない変更があったようだ。参考にしている本が古いと余分なところで時間を喰われる。

 最初にやったこと
models.py のモデル定義の中に
class Admin:
list_display(....)

を追加

 実際には、
新たに Admin 用の専用クラスを追加して、そこに list_display を追加し、admin.site.register() で、そのクラスを追加する

modles.py はこんな感じ
class Item(models.Model):
# class Admin:
# list_display = ('tags',)

from django.contrib import admin
class ItemAdmin(admin.ModelAdmin):
list_display = ('start_date','item_code',)


admin.py はこんな感じ
from django.contrib import admin
from ecsite.itempage.models import Item,ItemAdmin
from ecsite.itempage.models import Tag ^^^^^^^^^
from ecsite.itempage.models import typeTag

admin.site.register(Item,ItemAdmin)
^^^^^^^^^^
 参考になったページはこちら。バージョンの違いに要注意。

----
 aptana は一度使うと手放せないかも (^^;

 

2009年11月3日火曜日

aptana + dajngo 何とか使えるようになる

 前のエントリーで、
 起動するようになったのはいいんだけど、Debug で起動しても aptana の管理を離れてバックグラウンド化してしまう。
 こうなるとデバッガーの意味がないんですけど。
 正確には python のプログラムがひとつ起動したあと、子プロセスとして django の本体が起動する。で、aptana の管理が及ぶのは親のプロセスだけで、django 本体はデバッグも出来ないし aptana からは止めることも出来ない。
 これだと高機能エディターとしか使えないんですけど...。

 あきらめかけたところで、参考にしたサイトに書いてあったことを思い出す。
 'noreload' ってなによ?と調べてみると、非常に怪しい機能。Ver 1.0 でもサポートはしていて、前につける記号が '-' ではなく '--'。

 さっそく「プログラムの引数」に '--noreload' 追加すると、うまくいった。

 これで IDE のデバッグ機能が使えるようになった代わりに、止めずにコードを直してデバッグを進めることはできなくったわけだ。ま、待つ場所が一箇所のイベントドリブンだから大勢に影響はないか。

 結局 aptana + Pydev で Django のコードが開発できるようになるのに1日近くかかってしまった。新しいツールの導入コストはやっぱり安くない。

 これから使い方は覚えなきゃならないし、django のテンプレートは aptana が対応してないみたいだし、元が取れるのかなぁ?

aptana + django aptana で Django が動き出す

 aptana をインストールしたあと、こちらのページを見ながらプロジェクトを aptana の下に移動。

 オイラの環境では
「引数」タブの「プログラムの引数」に「runserver –noreload」と入力します。
のところで、'-noreload' のオプションを受け付けなかった。

 動かそうとすると、
Error: [Errno 10013] アクセス許可で禁じられた方法でソケットにアクセスしようとしました。
 ??。aptana って、admin 以外で実行しているの?とりあえず、コマンドプロンプットから実行しても同じエラーがでる。aptana を終了するとコマンドプロンプットからは正常に起動する。

 ネットでちょっと調べてみるとこんなページが
 なんだ、エラーメッセージが間違ってるじゃん。

 結局「プログラムの引数」を「runserver localhost:8001」にして正常に起動するようになった。

 起動するようになったのはいいんだけど、Debug で起動しても aptana の管理を離れてバックグラウンド化してしまう。
 こうなるとデバッガーの意味がないんですけど。

 やっぱりすんなりとは行かないものだ。

---
追記
runserver localhost:8001 --noreload
で動くようになりました。
 
 

2009年11月2日月曜日

Django Empty module name であせる

 汎用ビューに挑戦中、Value Error,Empty module name なるものが出てあせる。

 汎用テンプレートを空にしても同じエラーが出る。ということは、テンプレートの内容ではない。
 動いてるアプリケーションのソースを切り貼りしているだけなんだが...。ネットをちょっと探してもピッタリのものが出てこない。

 ネットの海におぼれる前に、直近でやったこととエラーメッセージを見てよく考える。

 結果、setting.py への追加に問題あり。

TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'ecsite.itempage..itempage_context.itempage_context',
)
 ピリオドがひとつ多くてファイルが探せないだけ。

 ロケットが明後日の方向に飛んでいかなくて良かった。

2009年11月1日日曜日

Django ようやく MVC がわかった

 ようやくMVC がどういうものか体感できた。テンプレートの使い方もわかってきた。

 大きな山を越えるとだいたいモチベーションが落ちて、尻切れトンボになることが多いので、ここが頑張りどころ。

 とりあえず動けばいいでコーディングを進めてきたので、一度リファクタリングでもしようか。