現時点でのnewforms

2007/02/21 01:58

※ 商品のリンクをクリックして何かを購入すると私に少額の報酬が入ることがあります【広告表示】

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

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

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

モデルフィールドには型が有り、テーブル生成時やフォームフィールドの型はモデルフィールドから(デフォルトが)決まる。

フォームフィールド生成ロジックはモデルフィールドにある。

oldformsのManipulatorのようなもの。

ユーティリティファンクションで、モデルクラスやモデルインスタンスから生成可能。

newformsが正式なformsとなった際には、汎用ビューにフォームも指定することになると思われる。

今回はウィジェットは無視

で、問題は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モデルのpos talcodeは間違いなく郵便番号系のフィールドを使うんだから…。

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

Prev Entry

Next Entry