フォトライフ

2006年09月26日(火) 01:01 この記事をクリップ!

 

Goodpicさんのところで知ったJPGというサービスが面白そうなのでエントリしてみました。
大きなサイズの写真が無いので、無理矢理過去のPhotoCDから引っぱりだしてきました。Photoshop使うなという指令を無駄に拡大解釈して無編集のため、リバーサルの枠まで含んでます。
鎌倉は隣町なのでホームタウンというと語弊がある気もしますが、子供の頃からうろうろしてるし、高校は鎌倉市だし、問題ないに違いないです。
最近はこのページのリニューアルを考えていて、unohさんのフォト蔵に登録してみたりして自分の写真を見る機会が増えました。久しぶりに一眼を持ち出そうかな。

ちなみに、JPGのBIGというテーマにあるWTCがちょっとブラック

 Django勉強会 Disc0 その後

2006年09月22日(金) 02:43 この記事をクリップ!

 

Django勉強会 Disc0、終了しました。


今回は、「チュートリアルをやってみよう」ということで、私の現場の人間を含め7チームに分かれてペアプロ(とトリオプロ?)にてチュートリアル実施という不思議な勉強会でした。

にもかかわらず20名という人数で行えたことは、皆々様のご協力あってこそです。
出入りが1名ずつありましたが、懇親会も20名をキープ!これって凄いかも:)
#懇親会を仕切っていただいた上村さんには、変なメンツが混入したことでご迷惑をおかけいたしました。

懇親会でのmopemopeさんコメントではありませんが、今年の2月の時点ではまさか9月にこんなことになっているとは想像もできませんでした(django-jaは、いつのまにやら125名になっています)。

django-jaは「Djangoユーザ会」ではなく「Djangoと日本の仲間たち」です。勉強会もちょっと暑苦しい系で続けていきたいと思います。
とはいっても、今後はもう少し突っ込んでいきますよー。

番外編

PythonでWin32経由でないExcelライブラリがあるとの情報。
pyexceleratorかな。なかなか期待できそう
DBTestCaseのPython版を作ろう。

 Django勉強会 Disc0

2006年09月15日(金) 20:55 この記事をクリップ!

 

Django勉強会をすることになりました。
会場の都合でトータル20名位しか許容できないので、まずはdjangoproject.jpdjango-jaでの告知&募集としました。
人の集まりかた次第でpython-ml-jpにも告知を行おうと考えていましたが、2日程度で予定人数に到達しました。
Djangoに対する関心は日本でもが高まってきているようです(本家ML2800人に大して日本は117人なのでまだまだですが)。

 Django勉強会 Disc0

2006年09月14日(木) 00:00 この記事をクリップ!

 

[2006年09月21日(木)のイベント]

Django勉強会を行います。

チュートリアルを流しつつ、今後の勉強会の方向性を模索します。

 pandoraに戻ってみた

2006年09月09日(土) 23:55 この記事をクリップ!

 

溜まりにたまっていたdjango-usersとdjango-developersのメールを流しつつ、ネットラジオを流しつつ。

ちょっとlast.fmに浮気をしてみたりしたんだけど、なんだかプレーヤが変わってから使い方わかんないし、pandoraにもどってみた。

やはりpandoraのGenomeというのが非常に良い。なんでも、音楽教育を施したスタッフが音楽を分析しているんだそうな。web2.0的アプローチじゃないところが素敵。

大好きなSt.Germainから推薦されたDubtribe Sound Systemというのに飛んだんだけど、St.Germainも含め、詳細な説明が付属している。
おんなじような音楽が好きな人が周りにいないし、普段誰の何って気にして聴いてないから(わからんから)、近所のCD屋のにいちゃん(ねぇちゃんかもしれない)の推薦版くらいしか導入がなかったわけ。
正式サービスインしたpandoraにはブックマーク機能とかユーザページとかができてた

どうでもいいけど、そんな感じの土曜日(実際は子供とトイレトレーニングとかいろいろ忙しい)。

 RailsのPagination

2006年09月08日(金) 00:04 この記事をクリップ!

 

業務に突っ込むLLは、Djangoにしたのでどうでも良いといえば良いんだけど、ちょっと気になったので。

RailsのPaginationって、result setをfetchする段階でcursor位置をずらしてるの?



まさかそんなことは無いとは思うんだけど、このへんとかこのへんとか見てると。。。また誤読かな?
誤読でないとしたら、Railsを使っている人たちはみんな気づいてる常識?大丈夫?
ま、どうでもいいんだけど、ソースを読んで確認する気力が無いので誰か教えて。

ワタシヲアンシンサセテクダサイ。

ちなみに、Djangoの場合はpagenate_byできちんとoffset/limitが吐かれます(当然か、きっとRailsもそうに違いない)。
Model.objects.all()[5:10]とかやってもSQLなところがすごいのです。

 DjangoのViewをテストする

2006年09月03日(日) 23:46 この記事をクリップ!

 

最近追加されたテスティングフレームワークを試したみた。

Djangoは基本的にはPython由来のdoctestやunittestを用いてテストを行う。最近追加されたテスティングフレームワークは、アプリケーションの直下にあるmodels.pyやtests.pyを自動的にAllテストしてくれるというもの+Viewのテストを行う疑似ブラウザともいえるClientというクラス。

Railsと同じく、Djangoもテストの前にテスト用データベース・テーブルを生成し、初期データを流し込み(fixtureは現在実装中)、テストを行い、テスト用データベースを破棄するという流れ。おいおい、そんな流れは業務系とか既存データベース使うアプリにはできんぞ、せめてビューとかシノニムとかに気づいてくれよー。
とか思いつつ。(現実的には、デフォルトのTEST_RUNNER設定であるdjango.test.simple.run_testsをそのままは利用せずに、ちょっと振る舞いをかえたTEST_RUNNERを利用することになるんだろうな。Djangoは素直にコードが書いてあるから自作も簡単だろう。)

doctest

きっとモデルやマネージャに対して有効な気がするテスト記述方式。つか、面白い。
manage.py test --settings=djengel.custom_settings とすると、テストが実施される。
このテストは、費目クラスの削除や表示フラグオフに対するテスト。削除も表示フラグオフも同じ動作になる。削除してもデータが消されないという肝心のテストが無いな・・。
class ExpenseItemManager(models.Manager) :
    """費目モデルのマネージャ。デフォルトのQuerysetに、非表示は取得しない、という条件を付与している。
    """
    def get_query_set(self) :
        return super(ExpenseItemManager, self).get_query_set().filter(visible=True)


class ExpenseItem(models.Model) :
    """費目を表すモデル。

    デフォルト動作の変更をいくつか実装してある。

        - デフォルトのdeleteを上書き
        - デフォルトのマネージャの上書き
        - カスタムマネージャの追加。
    >>> invisItem = ExpenseItem.objects.create(name="Test Invisible", max_amount=4000, food_cost=False, visible=True)
    >>> delItem   = ExpenseItem.objects.create(name="Test Delete"   , max_amount=4000, food_cost=False, visible=True)
    >>> before = ExpenseItem.objects.all()
    >>> invisItem in before
    True
    >>> delItem in before
    True
    >>> invisItem.visible=False
    >>> invisItem.save()
    >>> delItem.delete()
    >>> after = ExpenseItem.objects.all()
    >>> invisItem in after
    False
    >>> delItem in after
    False
    
    """
    name = models.CharField(_('Expense Item Name'), blank=False, maxlength=30)
    max_amount = models.IntegerField(_('Max Amount'), blank=False, default=0, help_text=_('Max amount per month.'))
    food_cost = models.BooleanField(_('Food Cost Flag'), default=False, help_text=_('weather food cost or not'))
    visible = models.BooleanField(_('Visible Flag'), default=True, help_text=_('if expense item is invisible, you can\'t edit anymore.'))
    objects = ExpenseItemManager() #デフォルトのマネージャをカスタムマネージャに変更
    summary_objects = ExpenseItemSummaryManager() #サマリー用のマネージャを登録

    class Admin :
        list_display = ("name", "max_amount", "visible", "food_cost")
        ordering = ['id']

    class Meta :
        verbose_name = _('Expense Item')
        verbose_name_plural = _('Expense Items')

    def __str__(self) :
        """オブジェクトの人間可読表現
        """
        return self.name

    def delete(self) :
        """費目を物理削除すると関連する出費も含めて削除されてしまうため、モデルを利用しての削除はできないようにしてある。

        代わりに、削除を呼ぶと「表示フラグ」をオフにするようにし、同時にマネージャをカスタムマネージャとし、デフォルトのQuerysetに「表示フラグ」オンという条件を入れるようにした。これにより、費目を管理画面から削除すると、「削除した費目を管理画面で編集できない」「削除した費目は出費の追加画面に候補として出てこない」という動作を実現している。
        """
        self.visible = False
        self.save()


unittest

同様のテストをunittestを使って記述するとこうなる。まぁ、普通。testメソッドで例外が発生してもきちんとtearDownが走る。
import unittest

from djengel.squander.models import ExpenseItem

class ExpenseItemTest(unittest.TestCase) :

    def setUp(self) :
        self.invisItem = ExpenseItem.objects.create(name="Test Invisible", max_amount=4000, food_cost=False, visible=True)
        self.delItem   = ExpenseItem.objects.create(name="Test Delete"   , max_amount=4000, food_cost=False, visible=True)

    def tearDown(self) :
        pass

    def test_normal(self) :
        before = ExpenseItem.objects.all()
        assert self.invisItem in before
        assert self.delItem in before	

    def test_delete(self) :
        self.delItem.delete()
        after = ExpenseItem.objects.all()
        assert self.delItem not in after

    def test_invisible(self) :
        self.invisItem.visible=False
        self.invisItem.save()
        after = ExpenseItem.objects.all()
        assert self.invisItem not in after


Viewのテスト

普段業務で使っているJavaでは、特定のリクエストをした際に、HttpServletRequestに何が保存されているかを確認している。FlexからたたくJavaの場合は単にリターンをチェックしている。
Viewテストで行いたいのは、この程度。可能か?
結論から言えば、余裕でまかなえる。以下のテストのtest_loginを見てもらうと、responseからcontextを取り出すためにおかしなコードを挟んでいることに気づくと思う。
このテストでリクエストを出しているpathは、権限チェックが含まれるviewなので、ログインしていない状態でリクエストを出すと1.ログイン画面にリダイレクトされる、2.ログイン画面からClient.loginでログイン用のViewにPostされログインを行う、3.test_loginでアクセスしようとしていたViewの結果がかえる、のでresponseが3回疑似ブラウザに渡されている。response.contextはこの3回の結果がリストとなって格納されている。contextにアクセスできるので、Viewで行った処理が正常かどうかを追うことができる(しかもリダイレクトされることまで追うことができる)。
ちなみに、Viewのテストにテストサーバの起動は不要。WSGIを使って疑似的(実は疑似ではない?)にリクエストを処理している。かなりたくさんの情報が取り出せる(responseの内容を表示してみれば何が入っているのかすぐわかる)ので、十分テスト可能。
import unittest

from djengel.squander.models import ExpenseItem

from django.test.client import Client
from django.contrib.auth.models import User, Permission

class SquanderViewTest(unittest.TestCase) :
    def setUp(self) :
        self.client = Client()
        self.user = User.objects.create_user('mam', '', 'mampass')
        view_permission = Permission.objects.get(codename__exact='can_view')
        self.user.user_permissions = [view_permission]

    def tearDown(self) :
        self.user.delete()

    def test_login(self) :
        respon = self.client.login('/djengel/summary/2006/08/','mam', 'mampass')
        last_response = respon.context[len(respon.context) - 1]
        assert '2006/07/' == last_response.get('prev_month', False)
        print last_response.__dict__

    def test_login_failed(self) :
        assert not self.client.login('/djengel/summary/2006/08/','dad', 'mampass')

 
ponybadge

Powered by

Feedbacks

Tweets

Tags

Calendar