2009年12月28日月曜日

デブロイ準備

 django で組んでいるアプリケーションが形になってきたのでそろそろインストールデブロイのことを考え始める。

 安そうななレンタルサーバーを探したが、今使っている xrea が格安・高機能なのでこれにインストールすることを前提に、同じバージョンの apach,python あたり自前のサーバーにインストールすることにする。

 

2009年12月20日日曜日

Django URL の長さって...

django の models.URLField に google map の URL コピペして、表示されたページのリンクから google map を表示させようとしたら
{errorText:"サーバーに接続できません。"}
 と出てきて地図が表示されない。

 調べていくと、google map の URL が 362 文字で、models.URLField の max_length の defautl が 200。

 200 文字でも結構なものだと思うが、では最長はいくつかと調べてみると...、ハッキリしないが IE の 2083 文字ブラウザの中では短めらしい。ただその IE も、ちょっといじると 4095 文字までは行くみたいなので、思い切って max_length=4096 でデータベースを作り直し。

 無事問題は解決したが、こういうのは富豪プログラミングのひとつか?いや、仕様がそれを要求しているんだろうなぁ。

2009年12月16日水曜日

Django djangoproject jp が落ちている

 ちょっと前も調子の悪いときはあったのだが、今回は昨日今日とアクセスできない。昨日はトップページは見られたのだが、今日はそれもだめ。

 むぅ、タダで使わせてもらっているので文句も言えんか。英語サイトしか読めないと効率落ちるなぁ (; ;)

2009年12月15日火曜日

Django まじですか

 サイドバーのあるいまどきのページを作って、サイドバー部分は Django に色々やらせてメインの部分は html のファイルを読み込ませて表示しようとした。

 テンプレート中で include タグを使って固定メッセージを読ませようとしたのだが、読み込まない。パスの指定を間違ったか、サブディレクトリを切ったのがまずかったかと色々試したがうまくいかない。
 すでに問題なく表示できている固定メッセージの html ファイルをそのディレクトリにコピーして表示させようとするとうまくいく。何度見直してもファイル名に間違いはない。ファイル名の構文解析の問題か?
 表示されないファイルの中身を、表示されるファイルにそっくりコピペすると...、表示される。

 ?????

 結局表示されないファイルの文字コードを aptana から utf-8 に設定すると表示されるようになった。default の s-jis 設定がまずかったらしい。

 テンプレートジェネレータが utf-8 のつもりで s-jis のファイルを読み込んで、動作がおかしくなったのか。

 いろんなところで日本語は面倒だ。
----
 もともと aptana の default 文字コードが s-jis なのが問題なのだからと、default を変更。
 google に「eclipse 文字コード 設定 デフォルト」と検索すると、最初に出てきたこちらのページにやり方が書いてあった。

 これでつまらんことに時間を取られることはなくなるはず。最初にやっておけばよかった。

Python BASIC でいうところの RIGHT$ とか

 数値を表す文字列をゼロパディングする必要があって、そういえば何10年も前に BASIC で
a$ = right$("000"+val$,4)
とかやったなぁと思い出す。

 さて Python では...、
a = ('000'+val)[-4:]
とかが割りと簡単に出てきた。

# a = '%04s' % val はだめみたいだ。

 だいぶ慣れたかなぁ、Python にも。

 だけど、C に勝るとも劣らないおかしな(?)書き方が目立ってきた。

----
 とか、いい気になっていたら、
a = val.rjust(4,'0')
で済むことがわかった。まだまだだなぁ。

 しかし、ライブラリというか、標準関数を覚えるのは苦手なんだよなぁ...。

2009年12月14日月曜日

JavaScript 初めてコードを書いてみた

 ページ上で数値を入力し、ボタンを押すとその数値を組み込んだ URL にジャンプさせたくなった。手元の本をひっくり返して JavaScript で実装。ついでだからと桁数制限と全角での数値入力も可能にした。

 で、書いたコードはこんな感じ。
function LC(obj){
// 全角数字 -> 半角数字に変換
var han= '1234567890';
var zen= '1234567890';
var word = obj.url.value;
for(i=0;i<zen.length;i++){
var regex = new RegExp(zen[i],"gm");
word = word.replace(regex,han[i]);
}
if (isNaN(word)) { // 数値以外を入力
alert("数値を入力してください");
} else {
if (word.length <= 4) { // 桁数が4桁以内
location.href='/item/'+word
} else { // 桁数が4桁を越えた
alert("4桁以下で入力してください");
}
}
}
 全角->半角変換は、こちらのページのコードを参考にさせていただいた。数字だけならもっと「エレガントな解法」がありそうな気もするが、良いことにしよう (^^;
----
 手元に JavaScript の本が2冊あるのだが、どちらも web page クラスライブラリの解説書みたいな感じで、言語としての JavaScript についてはあまり触れられていない。
 もう一冊文法書を買おうか、このあたりのページを見ながらなんとか乗り切ろうか...。

JavaScript 古い本を引っ張り出してきた

 ちょっと JavaScript のコードが必要になって、本棚から本を引っ張り出してきたら発行日が2000年。この手の本を買うときは必ず発行日を見て、古くないのを買っているので10年近く前に買った本ということになる。

 昔からやる気はあったのだが...、10年近く本を眠らせていたなんて。

 懲りずにがんばろう。

2009年12月13日日曜日

Django python 可変数キーワード引数に辞書オブジェクトを渡す方法

 クリエメソッドの filter の照合パラメタをプログラムで作りたくなった。定数でも動くのだが、プログラムで書ければコードが短くすっきりする。
 いろいろやってみたが、
filter('%s_tag__name=key' % tag)
とかやってもうまくいかない。

 色々調べたがうまくいかず、一度あきらめたのだが、どうしても使いたくなり再度調べてみた。ネットで色々検索し、aptana で breakpoint を設定してあーだこーだと調べていくうちに
filter(**kwargs)
のアスタリスク二つが気になった。これって C で言うところのポインタのポインタ?

 結局、
filter(**{'%s_tag__name' % tag:key})
でうまくいった。

 この手の「呼び出す側で変数の頭にアスタリスクを二つ重ねる」は、Django のコードの中にごろごろしているし、こちらのページに動作の解説があったのだが、意味が理解できずに読み飛ばしてしまった。

 答えは目の前に転がっていたのに...。

 修行が足りん。

2009年12月11日金曜日

django Pagination を使おうと思ったら

 アイテム数が増えたのでページングを追加しようと、サンプルプログラムを見てそれらしいキーワードを見つけ、検索をかけると一番最初にピッタリのページがヒット、したんだけど使い方が良くわからない。で、次のページを開くと最初のページの元の英文ページで使い方が書いてあった。

 こういうこともあるんだ。

 

2009年12月10日木曜日

Django snippet 妙なところで嵌った

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

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

Caught an exception while rendering: 'FieldFile' object is unsubscriptable

2009年12月6日日曜日

Django テンプレートタグを自作する

 テンプレートに可変長のリストを渡してテーブルを作る必要があった。で、cycle タグを使って何とかならないかと思ってやったら出来た。

 が、そこのコードをループで回すと2回目のループの最初が、直前のループの最後の続きになってしまう。

2009年12月4日金曜日

Django filter_horizontal が動かなかったわけ

 項目数の多くなりそうな ManyToManyField を追加したので filter_horizontal を入れたのだが、動かない。
複数選択するときには Control キーを押したまま選択してください。Mac は Command キーを使ってください
 などというメッセージは表示されるが、選択肢を選ぶ「窓」が全く表示されない。

 調べていくと...、

 ManyToManyField の verbose_name 引数に漢字を使っていたのだが、クオーテーションの前に u をつけていなかった orz。

 決められたことはキチンとやらないと...

Django フィルターを作っていて

 リストを引数に取ったはずが、文字列、それも aptana の watch window に表示される形そのままが引き渡される。

 あっちこっち調べていると...、

 ソースを良く見ると、フィルター宣言の前に @stringfilter というデコレーターが。
@register.filter
@stringfilter
def top_line(value):
 これはどうみてもだめでしょう。

 何も考えずにコピペしてはいかんなぁ。

2009年12月3日木曜日

python データ変換プログラムのデバッグ

 テーブルに変更があったのでデータを移行しようとしたらエラー...。

 調べていくとデータの中に '"'(ダブルクオーテーション)が入っていた。今回新たに html を追加したんだっけ。

 調べた結果、今回判ったこと。
 ということで、クオーテーションをダブルからシングルに替えて動くようになった。データにシングルクオーテーションが紛れたらどうなるかという問題は...、そのときはそのとき (^^;

 あと、覚えたてのリスト内包表記を使ってコードを少し縮めてみた。確かに短くなった上にわかりやすい。

2009年12月2日水曜日

Django HttpRequest の処理に嵌る

 条件検索を付加しようとして、check box で選択条件を入力し POST で送るところまでは出来たのだが、view に渡される request がうまく処理できない。
 aptana の変数表示を見ると、どう見ても値がリストの辞書なのだが、辞書のつもりで扱うとうまくいかない。値を取り出そうとするとリストの最後の要素しか取り出せない。

 よくよく見ると型が 'Querydict' となっている。フツーの辞書型じゃないの?と調べてみると...。
QueryDict オブジェクト

HttpRequest オブジェクト内では、 GET と POST 属性は django.http.QueryDict のインスタンスです。 QueryDict は辞書ライクなクラスで、同じキーに対して複数の値を取り得るようにカスタマイズされています。これは、 HTML のフォーム要素には、例えば <select multiple="multiple"> のように、同じキーに対して複数の値を渡すものがあるからです。
 ですと。「ライク」ってことは似て非なるものってことね。

 結局 getlistを使ってリストの形で引き出すことに成功。

 なんとか動いた。

 あとはブラッシュアップとバグ出しか。

 どこまで飽きずにモチベーションを維持できるか...

 

2009年12月1日火曜日

Django 0.96 向けのユーザー登録を 1.0 で動くように直した


 ユーザー登録自体は必要ないのだが、POST を使ってデータを送るサンプルで手元にあったのが、最新Pythonエクスプローラ の中のサンプルプログラム djmall のユーザー登録だけだったので、これを Ver 1.0 で動くようにした。

 一番戸惑ったのは、新規登録時の画面遷移がちょっとおかしい予想したのと違っていたこと。結局古い python + Django でプログラムを実際に動かして画面遷移を確認した。

 主な変更部分は以下の二つ。

  • User オブジェクトがだいぶ変わっていた。古いバージョンでは validation の機能もあったらしいが、1.0 からは 完全にモデルのサブクラスになっていて、validation は User から ModelForm で作ったフォームでおこなう
  • User のメンバ変数が変わっていた。last_login_date,last_login_time が last_login に、date_joined_date,date_joined_time が date_joined にそれぞれ一本化。validation に失敗したので、ソースを追っかけて判明。

 結果としてはこんなところだが、動くまでに2時間ほどかかってしまった。
 ま、POST 関連の動きもわかったし、良いことにしよう。

 ちなみに変更後のソースは以下のとおり。
from django.forms import ModelForm
class UserForm(ModelForm):
class Meta:
model = User

def regist(request):
if request.method == 'POST':
new_data = request.POST.copy()
now = datetime.now()
new_data.update({'last_login': now.strftime("%Y-%m-%d %H:%M"), 'date_joined': now.strftime("%Y-%m-%d %H:%M")})
manipulator = UserForm(new_data)
if manipulator.is_valid():
username = new_data['username']
email = ''
password = new_data['password']
user = User.objects.create_user(username, email, password)
user.is_staff = False
user.is_superuser = False
user.save()
return HttpResponseRedirect("%s%s" % (settings.MALL_BASE, '/accounts/login/'))
form = UserForm()
return render_to_response('registration/regist.html', {'form':form },context_instance=RequestContext(request))