Formsetsを使う3 - inlineformset_factory編

inlineformset_factoryとは

ForeignKey関係にあるオブジェクトを扱うときに便利な機能です。

model作成

ForeignKey関係にあるmodelを作成します。

models.py

from django.db import models

class Author(models.Model):
    author = models.CharField(max_length = 100)

    def __unicode__(self):
        return self.author

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length = 100)
    price = models.IntegerField()

    def __unicode__(self):
        return self.title

サンプルデータ作成

>>>from appname.models import Author
>>>Author(author = u'アガサ・クリスティ').save()
>>>Author(author = u'コナン・ドイル').save()

Form生成

作成したLiblaryFormsetを使ってHTMLを生成します。

>>>from appname.models import Author, Book
>>>from django.forms.modles import inlineformset_factory
>>>author = Author.objects.get(pk = 1)
>>>BookFormset = inlineformset_factory(Author, Book)
>>>formset = BookFormset(instance = author)
>>>print(formset)

とすると、長いHTMLが生成されるのでextraを使って1セットのHTMLを表示してみます。

>>>from appname.models import Author, Book
>>>from django.forms.modles import inlineformset_factory
>>>author = Author.objects.get(pk = 1)
>>>BookFormset = inlineformset_factory(Author, Book, extra = 1)
>>>formset = BookFormset(instance = author)
>>>print(formset)

HTMLは以下の通りです。(整形してあります)

<input type="hidden" name="book_set-TOTAL_FORMS" value="1"
    id="id_book_set-TOTAL_FORMS" />
<input type="hidden" name="book_set-INITIAL_FORMS" value="0"
    id="id_book_set-INITIAL_FORMS" />
<tr>
    <th><label for="id_book_set-0-title">Title:</label></th>
    <td>
        <input id="id_book_set-0-title" type="text" 
            name="book_set-0-title" maxlength="100" />
    </td>
</tr>
<tr>
    <th><label for="id_book_set-0-price">Price:</label></th>
    <td>
        <input type="text" name="book_set-0-price"
            id="id_book_set-0-price" />
    </td>
</tr>
<tr>
    <th><label for="id_book_set-0-DELETE">Delete:</label></th>
    <td>
        <input type="checkbox" name="book_set-0-DELETE"
            id="id_book_set-0-DELETE" />
        <input type="hidden" name="book_set-0-author" value="1"
            id="id_book_set-0-author" />
        <input type="hidden" name="book_set-0-id"
            id="id_book_set-0-id" />
    </td>
</tr>

ここにDeleteという、どのmodelにもない項目があります。
これはDjangoが自動的に付与した項目です。
必要ない場合は以下のようにすると表示されません。

>>>from appname.models import Author, Book
>>>from django.forms.modles import inlineformset_factory
>>>author = Author.objects.get(pk = 1)
>>>BookFormset = inlineformset_factory(Author, Book, extra = 1, can_delete = False)
>>>formset = BookFormset(instance = author)
>>>print(formset)

HTMLはこのように変わります。

<input type="hidden" name="book_set-TOTAL_FORMS" value="1"
    id="id_book_set-TOTAL_FORMS" />
<input type="hidden" name="book_set-INITIAL_FORMS" value="0"
    id="id_book_set-INITIAL_FORMS" />
<tr>
    <th><label for="id_book_set-0-title">Title:</label></th>
    <td>
        <input id="id_book_set-0-title" type="text" 
            name="book_set-0-title" maxlength="100" />
    </td>
</tr>
<tr>
    <th><label for="id_book_set-0-price">Price:</label></th>
    <td>
        <input type="text" name="book_set-0-price"
            id="id_book_set-0-price" />
        <input type="hidden" name="book_set-0-author" value="1"
            id="id_book_set-0-author" />
        <input type="hidden" name="book_set-0-id"
            id="id_book_set-0-id" />
    </td>
</tr>
twitter 2010-01-23 03:26:29.316972

関連ページ

参照サイト

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編