DjangoのForm関連の機能は手間を色々減らしてくれる気がするので、ぜひ使い方をマスターして活用したいな、と思っていたけど、かゆいところに手が届かいので、一部あきらめる。
[app/form.py]
from django import forms
from .models import Project
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ["field1", "field2", "field3"]
これだけでFormオブジェクトそのものはできちゃうので、Viewに1行くらいコンテキストに渡す処理書いてあげるだけで、Template側では
<form method="POST"> {% csrf_token %}
<fieldset class="module aligned">
{% for field in form %}
<div class="form-row"><div>
<label>{{ field.label_tag }}</label>
<div class="related-widget-wrapper">
{{ field }}
{{ field.errors }}
</div>
</div></div>
{% endfor %}
<input name="submit" type="submit" value="Regist" />
</fieldset>
</form>
これ書いてあげるだけでフォーム作ってくれちゃうし、こりゃ今後フィールド増えたときも便利だなあと確かに助かったんだけども、View側でPOSTを受け取ったときが困り物で
if(request.method == 'POST'):
form = ProjectForm(request.POST)
if not form.is_valid():
これ、Formのフィールドからはあえて削ったフィールドについては、手で横からセットしてあげることが多分できないんじゃないだろうか。無理やりrequest.POSTの中身をいじってから処理するのもなんか違う。上記の例だとformのオブジェクトに対してなんかメソッドやらでsetすることはできないのかと調べたものの出てこないし、Validationなんかも怪しいところだ・・・。
色々考えたすえ、ModelFormは画面の生成と一定のValidationでは頼ってみることにするけど、データ編集してDBにレコード保存する処理はModelで直で書いてあげることにする。これはもうその方がわかりやすい。
したら、Viewはこんなことになった。ピエン。
if(request.method == 'POST'):
form = ProjectForm(request.POST)
if not form.is_valid():
ctx['form'] = form
else:
p = request.POST
pj = Project(
field1=p['field1'],
field2=p['field2'],
field3=p['field3'],
field4=xxxxxxx, # Formからではなく自分で別の方法で取得させる
field5=xxxxxxx, # Formからではなく自分で別の方法で取得させる
)
pj.save()
messages.success(request, 'Success')
return redirect('xxxx:xxxxx')
いいのかなこれ。ちゃんと動いて、あとからメンテできればいいっていうポリシーでやってるけど、不安だ。