6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Django] フォームのフィールドを動的に生成する

Last updated at Posted at 2018-10-30

stack overflow で質問してた件が自己解決したのでQiitaに残して備忘録にしようと思い投稿しました.
初投稿なので温かい目で見てもらえればと思います.
#目的
ユーザーが指定した個数の入力フォームがほしい!
つまり動的にフィールドを追加してやりたかったわけです.
まあHTMLを直接追加してやれば出来るんですが,Djangoを使う以上でFormクラスでちゃんと管理してやりたいわけです.

ここに書いてある以外でもっといい書き方知ってたらコメントで教えてください.
#Formクラスの仕様
まずDjangoのFormクラスの仕様について自分の理解しているところをちょろっと書きます.
##フォームの基本的な使い方

forms.py
from django import forms

class TestForm(forms.Form):
    hoge = forms.CharField(label="hoge")
    fuga = forms.CharField(label="fuga")

上のコードで作ったTestFormを作って,例えばformとかいう名前でテンプレートに投げてやれば{{ form.as_p }}とか{{ form.as_table }}とかでinputフォームが出てくる.(この辺はDjangoの公式? Documentationこことか別記事を参照.)
特にフォームをバラバラの位置に出したいときなど,個別にフォームを指定したいときは,{{ form.hoge }}のように指定します.
##問題点:変数名=フィールド名
さて,今一度forms.pyのコードを見てもらうと,クラス直下で定義した変数名がそのままフィールド名になっていることが分かります. django.forms を見てみるとどうもFormクラスはBaseFormというクラスを継承しているのですが,その際にメタクラスを使ったりして(この辺はよく理解していません)変数名をキー,定義したフィールドを値にしてfieldsという辞書型配列に格納しているようです.ですのでforms.py で書いたクラスに配列で変数を定義したりしてもダメっぽいんですね.

#対策
配列を入れるとその配列の要素を名前とするフィールドをもつFormクラスを返してくれるような関数を作りました.

forms.py
from django import forms

def create_form(myary, *arg):
    f = forms.Form(*arg)
    for val in myary:
        f.fields[val] = forms.CharField(label=val)
    return f

こんな感じで行けました!

views はこんな感じ

views.py
class FormView(TemplateView):
    def __init__(self):
        self.keys = range(5)
        self.params = {
            'form':test(self.keys),
        }
    def get(self, request):
        return render(request, 'temlate.html', self.params)
    def post(self, request):
        self.params['form'] = test(self.keys, request.POST)
        return render(request, 'template.html', self.params)

ここではrange(5)を渡してやってます.POSTのときにはrequest.POSTを一緒に投げてやる.
#改善点
引数のとこなんかは辞書型にしてやったり,labelとかバリデーションなんかの設定も投げれる様にすればよさげ

書いてて気づいたんですけど,たしかJSONでFormクラス作れたような...

6
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?