現時点でのnewforms

2007年02月21日(水) 01:58 この記事をクリップ!

localflavorの登場でしかたなく、Djangoのnewformsをちょっとさわってみた。


Djangoの素敵な点として、モデルとしての特性は全てModelに記述するというものがあるわけだけど、現時点でのnewformsはどうなのかと。ちょちょいとさわってみただけなので、変かもしれないです。



まず、前提としてnewformsを構成するものたち。


  1. モデル + モデルフィールド
    データベースに対応するO/Rのモデルを意味する。
    モデルフィールドには型が有り、テーブル生成時やフォームフィールドの型はモデルフィールドから(デフォルトが)決まる。
    フォームフィールド生成ロジックはモデルフィールドにある。
  2. フォーム + フォームフィールド
    入力のバリデーションや、入力値(文字列)のPythonデータ化、保存ロジックまでを含むフォーム。
    oldformsのManipulatorのようなもの。
    ユーティリティファンクションで、モデルクラスやモデルインスタンスから生成可能。
    newformsが正式なformsとなった際には、汎用ビューにフォームも指定することになると思われる。
  3. ウィジェット
    HTML(とは限らないが)として表示する際に、どのようにレンダリングするかの部品。
    今回はウィジェットは無視


で、問題はlocalflavorに日本の郵便番号に対応するフォームフィールドを追加した場合に、どのようにそのフォームフィールドを使用するのかということ。



モデルがこんな感じだったとする。

from django.db import models
from django.contrib.localflavor.jp import models as jp_models
from django.contrib.localflavor.jp import forms as jp_forms
from django.contrib.localflavor.jp.validators import isValidJPPostalCode
from django.contrib.localflavor.jp.jp_prefectures import JP_PREFECTURES

class Address(models.Model):
    name = models.CharField(maxlength=50)
    postalcode = models.CharField(validator_list=isValidJPPostalCode, maxlength=8)
    pref = models.CharField(maxlength=16, choices=JP_PREFECTURES)

models.CharFieldを利用すると、フォームではnewforms.CharFieldが利用される。
ちなみに、現時点ではvalidator_listやchoicesを用いたバリデーションがnewformsでは行われない。



django.newforms.form_for_modelのformfield_callbackを使ってみる

formfield_callbackは、デフォルトではmodels.XxxField.formfieldを呼び出してnewforms.XxxFieldを返すようになっている。
from django import newforms as forms
from addressbook.address.models import Address
from django.contrib.localflavor.jp import forms as jp_forms
from django.contrib.localflavor.jp.validators import isValidJPPostalCode

def zip_field(f):
    if f.name == 'postalcode':
        return jp_forms.JPPostalCodeField(postal_validator= isValidJPPostalCode)
    return f.formfield()

AddressForm = forms.form_for_model(Address, formfield_callback=zip_field)
data = {'name': 'test', 'postalcode': '251-003', 'pref': 'kanagawa'}
f = AddressForm(data)
f.is_valid()
ヒドス


気を取り直して、django.newforms.form_for_modelのformにカスタムフォームを突っ込んでみる

カスタムフォームには、newforms.XxxField生成の振る舞いを変えたいものだけを定義すれば良い。
class AForm(forms.Form):
        postalcode = jp_forms.JPPostalCodeField(postal_validator= isValidJPPostalCode)

AddressForm = forms.form_for_model(Address, form=AForm)
data = {'name': 'test', 'postalcode': '251-003', 'pref': 'kanagawa'}
f = AddressForm(data)
f.is_valid()
んー。models.XxxFieldを定義した方がスマートだよねぇ。ここだけ振る舞いを変えるならまだしも、Addressモデルのpostalcodeは間違いなく郵便番号系のフィールドを使うんだから…。


Manipulator風にやってみる!

AddressForm = forms.form_for_model(Address)
AddressForm.base_fields['postalcode'] = jp_forms.JPPostalCodeField(postal_validator= isValidJPPostalCode)
data = {'name': 'test', 'postalcode': '251-003', 'pref': 'kanagawa'}
f = AddressForm(data)
f.is_valid()
うぬんうぬうぬorz


 
ponybadge

Powered by

Feedbacks

Tweets

Tags

Calendar