動的なformを作る 4 - 文字列からformオブジェクトを作成する widgets変更編

win-django.com - 動的なformを作る 3 - 文字列からformオブジェクトを作成する 基本編では、表現が少ないのでwidgetなどを変更することにより広がりがでてきます。

仕様

  1. '名前'フィールド(name)を作成し、CharFieldとします。
  2. '年齢'フィールド(age)を作成し、IntegerFieldとし2桁まで入力できます。
  3. '身長'フィールド(height)を作成し、DecimalFieldとし、整数は3桁、小数は1桁とします。
  4. '体重'フィールド(weight)を作成し、DecimalFieldとし、整数は3桁、小数は1桁とします。
  5. '備考'フィールド(note)を作成し、CharFieldとしTextareaにします。

上記のfieldを持つ'PersonalForm'という名前のformを作成します。
classでいうと、

from django import forms
from django.forms import Textarea

class PersonalForm(forms.Form):
    name = forms.CharField()
    age = forms.IntegerField(attrs = {'maxlength': '2'})
    height = forms.DecimalField(max_digits = 5, decimal_places = 2)
    weight = forms.DecimalField(max_digits = 5, decimal_places = 2)
    note = forms.CharField(widget = Textarea())

となります。

下準備

前回と同じように、moduleの文字列とmoduleをインポートする関数を作成します。

>>>FORM = 'django.forms'
>>>def mod_import(name):
>>>    mod = __import__(name)
>>>    components = name.split('.')
>>>    for comp in components[1:]:
>>>        mod = getattr(mod, comp)
>>>    return mod

fieldの作成

'name'のfieldを作成します。

>>>form = mod_import(FORM)
>>>f = getattr(form, 'CharField')
>>>f1 = f()
>>>f1.label = u'名前'

次に'age'のfieldを作成します。

>>>f = getattr(form, 'IntegerField')
>>>f2 = f()
>>>f2.label = u'年齢'
>>>f2.widget.attrs = {'maxlength': '2'}

'height'のfieldを作成します。

>>>f = getattr(form, 'DecimalField')
>>>f3 = f()
>>>f3.label = u'身長'
>>>f3.max_digits= 5
>>>f3.decimal_places = 2

'weight'のfieldを作成します。

>>>f = getattr(form, 'DecimalField')
>>>f4 = f()
>>>f4.label = u'体重'
>>>f4.max_digits= 5
>>>f4.decimal_places = 2

最後に'note'のfieldを作成します。

>>>f = getattr(form, 'CharField')
>>>f5 = f()
>>>f5.label = u'備考'
>>>w = getattr(form, 'Textarea')
>>>w.attrs = {'cols': '10', 'rows': '40'}
>>>f5.widget = w()

formオブジェクト作成

>>>fields = {'name': f1, 'age': f2, 'height': f3, 'weight': f4, 'note': f5}
>>>pf = type('PersonalForm', (getattr(form, 'BaseForm')), {'base_fields': fields})

これでformオブジェクトが作成されました。

HTML出力

作成したformオブジェクトをHTMLで表示してみます。

>>>PF = pf()
>>>PF.as_p()

以下が出力されたHTMLです。

<p><label for="id_name">名前:</label>
   <input type="text" name="name" id="id_name" /></p>\n
<p><label for="id_age">年齢:</label>
    <input id="id_age" type="text" name="age" maxlength="2" /></p>\n
<p><label for="id_height">身長:</label>
    <input type="text" name="height" id="id_height" /></p>\n
<p><label for="id_weight">体重:</label>
    <input type="text" name="weight" id="id_weight" /></p>\n
<p><label for="id_note">備考:</label>
    <textarea id="id_note" rows="10" cols="40" name="note"></textarea></p>
twitter 2009-11-14 15:21:10.582299

関連ページ

Recent Updates

URLConf Tip 01 - キャプチャの有無にかかわらず同一のviewで処理する
Markdownの入力補助"wmd"をAdmin siteで使う
ModelFormでfieldのwidgetを変更する
動的なformを作る 6 - Dynamic Inline Admin site編
Formsetsを使う3 - inlineformset_factory編
動的なformを作る 5 - django-dynamic-formset編
Formクラスからメディアを定義する
複数のmodelを結合する 2 - Proxy model編
複数のmodelを結合する 1
ModelFormでfieldの表示順番を変える
Admin siteのwidgetを個別に変更する
formfield_overridesを使ってAdmin siteのwidgetを変更する
Admin siteのlist_displayをカスタマイズする - リンク編
Admin siteのlist_displayをカスタマイズする - 基本編
Admin siteのTextareaの高さを自在に変更する - admin.py編