動的なformを作る 5 - django-dynamic-formset編

多数のデータを入力する際、1件ごとにPostするシステムは不便です。
一括して入力し、1度のPostで登録できるようになれば便利です。

django-dynamic-formsetを参考にして作成してみましょう。

仕様

  1. jQueryを使用します。
  2. django-dynamic-formsetを利用します。

Formsetsクラスを使って構築

まずはdjango-dynamic-formsetからjquery.formset.jsをダウンロードし設置します。

そして、jquery.formset.init.jsを作成します。

jquery.formset.init.js

$(function() {
    $('#dynamicform').formset()
})

次にform.pyと、views.py(GET部分のみ)を作成します。

forms.py

from django import forms
from django.forms import formset

class AuthorForm(forms.Form):
    author = forms.CharField(max_length = 50, label = 'Author')

    class Media:
        js = (
            '/media/js/jquery.js',
            '/media/js/dynamicform/jquery.formset.js',
            '/media/js/dynamicform/jquery.formset.init.js',
        )
AuthorFormset= formset.formset_factory(AuthorForm)

views.py

from django.shortcuts import render_to_response
from appname.forms import AuthorFormset

def dynamicform(request):
    formset = AuthorFormset()
    return render_to_response('dynamicform.html', {'formset': formset})

templateを作成します。

dynamicform.html

<html>
<head>
    {{ formset.media }}
</head>
<body>
<h3>DynamicFormset</h3>
<form action = "." method = "post">
    <table>
        <tbody>
            <tr><td>Author</td></tr>
            {% for form in formset %}
            <tr id = "dynamicform"><td>{{ form.author }}</td></tr>
            {% endfor %}
        </tbody>
    </table>
    {{ formset.management_form }}
    <input type = "submit" value = "Add">
</form>
</body>
</html>

表示してみましょう。

dynamicform01_01

数件追加してみました。

dynamicform01_02

入力したデータをmodelへ追加する

まず入力したデータを追加するmodelを作成します。

models.py

from django.db import models

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

    def __unicode__(self):
        return self.author

dynamicformメソッドに処理を追加します。

views.py

from django.shortcuts import render_to_response
from appname.forms import Author

def dynamicform(request):
    if request.method == 'POST':
        formset = AuthorFormset(request.POST)
        if formset.is_valid():
            data = formset.cleaned_data
            for form_data in data:
                Author(**form_data).save()
            return render_to_response('posted.html', dict(data = data))
    else:
        formset = AuthorFormset()
        return render_to_response('dynamicform.html', {'formset': formset})

最後に登録したデータを表示するページを作成します。

posted.html

<html>
<head>
</head>
<body>
<h3>Posted Data</h3>
<p>{{ data|length }}</p>
<p>
{% form_data in data %}
    {% row in form_data.items %}
    {{ row.1 }}
    {% endfor %}
{% endform %}
</p>
</body>
</html>

実際にデータを入力して実行してみます。

dynamicform01_03

Postしてみます。

dynamicform01_04

twitter 2010-01-21 02:42:37.709908

関連ページ

参照サイト

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編