Ian Lewis
Ian Lewis is a web developer living in Tokyo Japan. His current interests are in Django, python, alternative databases and rapid web application development. About Me...
  • Django modelformset_factory便利

    Django は複数のフォームのデータを同時に扱えるために、FormSetsというものを用意しているんですけど、実は、ModelFormのFormSetでも使える。クエリーの結果のデータのModelFormを一個一個、一つのページに出すにはこんなコードを書ける。

    from django.forms.models import modelformset_factory
    
    formset = modelformset_factory(
        MyModel,
        fields=('status','content'),
        extra=0,
    )(queryset=MyModel.objects.filter(status=1))
    

    便利

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - Django modelformset_factory便利
  • daemontoolsを使ってdjango fastcgiのデーモンを設定する

    daemontoolsの上にdjango fastcgiを使うのは簡単にできるけど、正しいユーザとして、フォアグラウンドに起動するにはbashとdaemontoolsの設定する必要がある。

    フォアグラウンドに起動するには、daemonize=falseを指定する必要がある。

    それで、起動するデイモンはユーザを指定するオプションがないとrootユーザとして、起動する。runfcgi はそういうオプションがないので、daemontools の setuidgid ツールを使う。

    setuidgidのコマンドになるので、プロセスの標準パイプを正しく接続するには、bashのexecコマンドを使う。

    /service/myapp/run

    #!/bin/bash
    
    BASEDIR="/home/www/"
    PIDFILE="$BASEDIR/app.pid"
    
    exec setuidgid www python /home/www/django-prj/manage.py runfcgi \
        --settings=settings_production method=threaded  port=8001 \
        pidfile=$PIDFILE daemonize=false 2>&1
    
    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - daemontoolsを使ってdjango fastcgiのデーモンを設定する
  • DjangoのHTTPS対応開発サーバ

    Djangoの開発サーバはHTTPSを普段に対応してないので、HTTPS対応をどうやって開発すればいいんだろうと思ったら、調べてみた。秘密は開発サーバ、http用とhttps用を二つ立ち上げます。https開発サーバはstunnelでHTTPS対応します。stunnelは普通のソケットをSSL tunnelingをしてくれます。

    このドキュメント を使います。

    stunnel をインストールしてから、pemファイルを作ります。

    openssl req -new -days 365 -nodes -out newreq.pem -keyout /etc/stunnel/stunnel.pem
    

    stunnel の設定ファイルを適当なところに保存します (これから、dev_https)。acceptはhttpsサーバのポート。connectはhttps用の開発サーバのポートになります。

    pid =
    
    [https]
    accept=8002
    connect=8003
    

    stunnel に設定ファイルを指定してdaemonを立ち上げます

    stunnel dev_http
    

    https用の開発サーバを立ち上げます。 HTTPS=on の環境変数を設定しておけば、 request.is_secure()などは Trueをちゃんと返す。

    HTTPS=on python manage.py runserver 0.0.0.0:8003
    

    http用のサーバを立ち上げる

    python manage.py runserver 0.0.0.0:8000
    

    これで、 http://localhost:8001https://localhost:8002 で接続することができる。

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - DjangoのHTTPS対応開発サーバ
  • Django redirect_to はnon-ascii URLに対応してない

    Django は一般的なリダイレクトするビューを django.views.generic.simple.redirect_to に用意していますけど、unicodeのキーワードがあれば、動かないのが最近見つけた。

    Djangoプロジェクトのurls.pyでこういう風にURLの設定を書けます。

    from django.conf.urls.defaults import *
    
    urlpatterns = patterns('django.views.generic.simple',
        url(r'^jp/(?P<tag_name>.+)\;', 'redirect_to', {'url': '/jp/tag/%(tag_name)s'}),
    )
    

    そうした場合、redirect_to は tag_nameに入ったデータをリダイレクト先にURLに入れてくれます。が、そのデータはasciiでない場合、redirect_to の中にtag_nameのデータに入れたURLを urlquoteに特に渡すなど、特に何もしないで、HttpResponseRedirectに渡す。redirect_toはDjango 1.1でこの通り

    def redirect_to(request, url, permanent=True, **kwargs):
        """
        Redirect to a given URL.
    
        The given url may contain dict-style string formatting, which will be
        interpolated against the params in the URL.  For example, to redirect from
        ``/foo/<id>/`` to ``/bar/<id>/``, you could use the following URLconf::
    
            urlpatterns = patterns('',
                ('^foo/(?P<id>\d+)/$', 'django.views.generic.simple.redirect_to', {'url' : '/bar/%(id)s/'}),
            )
    
        If the given url is ``None``, a HttpResponseGone (410) will be issued.
    
        If the ``permanent`` argument is False, then the response will have a 302
        HTTP status code. Otherwise, the status code will be 301.
        """
        if url is not None:
            klass = permanent and HttpResponsePermanentRedirect or HttpResponseRedirect
            return klass(url % kwargs)
        else:
            return HttpResponseGone()
    

    最終的に、この問題が起こる時に、このエラーが出る。

    UnicodeEncodeError: 'ascii' codec can't encode characters in position 8-11: ordinal not in
      range(128), HTTP response headers must be in US-ASCII format
    

    実際は下バグが既にあって、HttpResponseRedirectの中で、asciiでないURLをちゃんとエンコードするはず。

    #11522 Crash on redirect to a relative URL if request.path is unicode

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - Django redirect_to はnon-ascii URLに対応してない
  • 明日からPython温泉

    明日からPython温泉に参加しに行ってきます。課題は下記のとおり

    どこまでできるかわかんないけど、たぶんあまり眠らないでしょう。

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - 明日からPython温泉
  • Python 例外のひどい仕様

    Pythonの例外オブジェクトは苦手です。例外のメッセージが何でもasciiとして扱われることがひどい。

    In [1]: t = ValueError("テスト".decode("utf8"))

    In [2]: print t
    ---------------------------------------------------------------------------
    UnicodeEncodeError                        Traceback (most recent call last)

    /home/ian/src/project/<ipython console> in <module>()

    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

    In [3]: t = ValueError(u"テスト") # Unicode object's don't work either

    In [4]: print t
    ---------------------------------------------------------------------------
    UnicodeEncodeError                        Traceback (most recent call last)

    /home/ian/src/project/<ipython console> in <module>()

    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

    Djangoのテストフレームワークで、doctestを使おうと思ったら、例外のメッセージがasciiじゃないとダメというのが判明

    u"""
    >>> test(-1)
        Traceback (most recent call last):
            ...
        ValueError: エラーですよ!
    """

    とやっても、うまくうごかない。以下のUnicodeDecodeErrorがでる

    ======================================================================
    ERROR: Doctest: app.tests
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/home/ian/.virtualenvs/test/lib/python2.5/site-packages/django/test/_doctest.py", line 2175, in runTest
        test, out=new.write, clear_globs=False)
      File "/home/ian/.virtualenvs/test/lib/python2.5/site-packages/django/test/_doctest.py", line 1403, in run
        return self.__run(test, compileflags, out)
      File "/home/ian/.virtualenvs/test/lib/python2.5/site-packages/django/test/_doctest.py", line 1291, in __run
        got += _exception_traceback(exc_info)
      File "/home/ian/.virtualenvs/test/lib/python2.5/site-packages/django/test/_doctest.py", line 269, in _exception_traceback
        return excout.getvalue()
      File "/usr/lib/python2.5/StringIO.py", line 270, in getvalue
        self.buf += ''.join(self.buflist)
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 24: ordinal not in range(128)
    
    ----------------------------------------------------------------------
    

    Update: moriyoshiさんにより、Python 2.6 でちゃんと動くみたい

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - Python 例外のひどい仕様
  • Django 勉強会 Disc. 8 参加して来た

    。。というか、ハンズオンC Django on GAEのセッションを担当させていただきました。まさかこんなに人気があると思わなかったけど、皆さんはびっくりするほど勢いを持ってきて、感動しました。

    Pollsというアプリを動かすまで出来た人がほとんどで、すごくうれしい思い出ができました。

    Django Benkyoukai Disc. 8 Hands-on C (GAE)

    みなさんお疲れ様でした!

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - Django 勉強会 Disc. 8 参加して来た
  • Django勉強会Disc.8の資料をRSTにした

    id:tokibito見つけてくれた rst2pdf を使ってid:tmatsuoDjango勉強会Disc.8 ハンズオンC の資料をPDFにした。

    ほとんど id:tokibitoと同じやり方でPDFを吐き出したけど、問題点が二つあった。

    rst2pdf をたたくと ja.jsonを指定する上、font-directoryも指定しないと日本語が化ける。Ubuntuの場合 VL-Gothicで充分なので、

    rst2pdf -s ja.json,perldoc.json --font-folder="/usr/share/fonts/truetype/vlgothic" django-hack-a-thon-get-handson.part2.rst

    問題点の二つ目は、rst2pdfの wordWrapが段落に対して、一つのフラグメント(?)しか扱えないようで、エラーが出た。

    [ERROR] styles.py L191 Error processing font VL-Gothic-Regular: Can't open file "ipam.otf"
    [ERROR] styles.py L192 Registering VL-Gothic-Regular as Helvetica alias
    Traceback (most recent call last):
      File "/usr/bin/rst2pdf", line 8, in 
        load_entry_point('rst2pdf==0.9', 'console_scripts', 'rst2pdf')()
      File "/usr/lib/python2.5/site-packages/rst2pdf-0.9-py2.5.egg/rst2pdf/createpdf.py", line 1212, in main
        compressed=options.compressed)
      File "/usr/lib/python2.5/site-packages/rst2pdf-0.9-py2.5.egg/rst2pdf/createpdf.py", line 991, in createPdf
        pdfdoc.build(elements)
      File "/usr/lib/python2.5/site-packages/Reportlab-2.1-py2.5.egg/reportlab/platypus/doctemplate.py", line 740, in build
        self.handle_flowable(flowables)
      File "/usr/lib/python2.5/site-packages/Reportlab-2.1-py2.5.egg/reportlab/platypus/doctemplate.py", line 638, in handle_flowable
        if frame.add(f, self.canv, trySplit=self.allowSplitting):
      File "/usr/lib/python2.5/site-packages/Reportlab-2.1-py2.5.egg/reportlab/platypus/frames.py", line 141, in _add
        w, h = flowable.wrap(aW, h)
      File "/usr/lib/python2.5/site-packages/Reportlab-2.1-py2.5.egg/reportlab/platypus/paragraph.py", line 567, in wrap
        self.blPara = self.breakLinesCJK([first_line_width, later_widths])
      File "/usr/lib/python2.5/site-packages/Reportlab-2.1-py2.5.egg/reportlab/platypus/paragraph.py", line 819, in breakLinesCJK
        raise ValueError('CJK Wordwrap can only handle one fragment per paragraph for now')
    ValueError: CJK Wordwrap can only handle one fragment per paragraph for now
    

    なので、面倒くさいから、wordWrapを無効にした。

    {
      "embeddedFonts" :
    [["VL-Gothic-Regular.ttf","VL-PGothic-Regular.ttf","ipam.otf","verdanaz.ttf"]],
      "fontsAlias" : {
        "stdFont": "VL-PGothic-Regular",
        "stdBold": "VL-PGothic-Regular",
        "stdItalic": "VL-PGothic-Regular",
        "stdMono": "VL-Gothic-Regular"
      },
      "styles" : [
        ["base" , {
          "wordWrap": "None"
        }],
        ["literal" , {
          "wordWrap": "None"
        }]
      ]
    }
    

    bitbucketに保存してる。

    PDF

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - Django勉強会Disc.8の資料をRSTにした
  • Google Appengine SDK 1.1.8がリリースされました

    Appengineの新しいリリース1.1.8が来た。色な面白いところがあるけど、仲居さん(id:Voluntas)のブログポストからピックアップする。

    • ByteStringProperty が実装 気軽に使える BlobProperty
    • UserProperty に auto_current_user / auto_current_user_add が追加。
      • DateTimeProperty と同じ動作すると思われ。
    • PolyModel が追加されました。
      • Django の継承と一緒、使い方は簡単です。
      from google.appengine.ext import db
      from google.appengine.ext.db import polymodel

      class Entity(polymodel.PolyModel):
        created = db.DateTimeProperty()

      class Status(Entity):
        message = db.StringProperty()

      class Clip(Entity):
        url = db.StringProperty()
    • Image API に width/height が実装されました
    • db.Model.order() にて __key__ のソートが出来るようになりました。bugfix

    僕が気になったところがもう一個あるんだけど、このリリースにて、antlr3というモジュールが必須となった。1.1.8をインストールして動かそうたしたら、

    ImportError: No module named antlr3

    が出てきた。理由はappengine_djangoを使ってること。appengine_djangoはgoogle_appengine/lib/antlr3のモジュールをインポートしてなかったので、エラーが出てきた。appengine_djangoのSVNの最新版を使えば、解決する。

    何で、antlr3が必要になったというと、実際コード見ると、google_appengine/google/appengine/cronで、groc.py, GrocLexer.py, GrocParser.pyがある。grocというcronみたいなサービスがもうすぐ出るかもしれないね。GrocLexer.pyとGrocParser.pyはantlr3を使ってcronの時間設定文字列を解析するパーサーだという。面白い。

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - Google Appengine SDK 1.1.8がリリースされました
  • Django 勉強会 Disc.7

    昨日、アクセンス・テクノロジーの東京本社にDjango 勉強会 Disc.7に参加しに行ってきました。

    GeoDjango

    最初は松尾さんgeodjangoの話。

    • GeoDjangoのDBサポートはpostgisが一番対応してます。
    • Adminで地形のエリア編集などは地図のJavascriptアプリで楽々
    • GeoDjangoのGeoManagerでfilter(field__poly_contains=point)ができる。

    ContentType

    次は増田さんのGenericForeignKeyの話と、次に岡野さんのContentTypeの話

    • GenericForeignKeyはContentTypeとobject_idのフィールドのラッパーに過ぎない
    • ContentTypeでModelの処理が結構一般的にできる(岡野さんのサンプルアプリ)
    • ContentTypeManagerのget_for_model()と、ContentTypeのget_object_for_this_type()で色な面白いことができる。
  • モバイル

    次に、OpenIdの話と、最後に酒徳さんDjangoでモバイルサイトの話

    • モバイルの開発は大変
    • セッションを使わずにurlでフォームウィザードみたいなのを作るのがあり
    • gumiがよくできてる。

    まとめ

    • アクセンス・テクノロジーの人たちに感謝
    • 懇親会で酒徳さんと松尾さんといい話をして楽しかった
    • アクセンスから、かっこいい手帳をもらった。
    参加したみんなさん、お疲れ様でした!
Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - Django 勉強会 Disc.7