attribute: Phillie Casablanca

Djangoで動的にフォーム(Form)のフィールド(field)を作る



Djangoの遊びプロジェクットをやっています。

そこで、ユーザが入力する項目から、複数選択可能チェックボックスのFormが作りたくて困っていました。

下記のモデルを定義しました:

models.py


class SkillCategory(models.Model):
name = models.CharField(max_length=50)

class Skill(models.Model):
category = models.ForeignKey(SkillCategory)
name = models.CharField(max_length=50)

Djangoの開発者らしいサイトから、So you want a dynamic formでの説明から、下記の答えがわかりました。

ここで、モデルで定義するSkillやSkillCategoryから、FormのFieldが動的に作成されます。
forms.py


from django import forms
from myapp.models import Skill
def get_categorized_skills():
    skills = {}
    for s in Skill.objects.values('pk', 'name', 'category__name').order_by('category__name'):
        if s['category__name'] not in skills.keys():
        skills[s['category__name']] = []
        skills[s['category__name']].append((s['pk'], s['name']))
    return skills

class SkillSelectionForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(SkillSelectionForm, self).__init__(*args, **kwargs)
        skills = get_categorized_skills()
        for idx, cat in enumerate(skills.keys()):
# ascii以外(日本語)の名前が使えるようにfield_name・display_nameを作成します。
field_name = u'category-%d' % (idx)
display_name = cat
            self.fields[field_name] = forms.MultipleChoiceField(choices=skills[cat],
label=display_name,
widget=forms.CheckboxSelectMultiple)


monkut // Sept. 13, 2009 // 10:07 p.m.