最初のフォームの結果で 2 番目のフィールドとそのラベルの数を決定する必要があると仮定しています。Django フォーム ウィザードを調べることをお勧めします。__init__
しかし、フォームセットのメソッドを利用してフォームラベルを変更する、単純な非フォームウィザード(そしておそらく理想的/保守性が低い)方法を次に示します*:
フォーム.py:
# File: forms.py
from django import forms
from django.forms.formsets import BaseFormSet
# What you've called 'GetMachine'
class MachineForm(forms.Form):
no_of_lines = forms.IntegerField(max_value=4)
# What you've called 'GetLine'
class LineForm(forms.Form):
beamline_name = forms.CharField(max_length=15, label='Name of Beamline')
# Create a custom formset and override __init__
class BaseLineFormSet(BaseFormSet):
def __init__(self, *args, **kwargs):
super(BaseLineFormSet, self).__init__(*args, **kwargs)
no_of_forms = len(self)
for i in range(0, no_of_forms):
self[i].fields['beamline_name'].label += "-%d" % (i + 1)
ビュー.py:
# File: views.py
from django.forms.formsets import formset_factory
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from forms import MachineForm, LineForm, BaseLineFormSet
def get_no_of_lines(request):
if request.method == 'POST':
machine_form = MachineForm(request.POST)
if machine_form.is_valid():
# At this point, form fields have already been
# converted to Python data types :)
# so no need to convert `line_no` to an integer
no_of_lines = machine_form.cleaned_data['no_of_lines']
return HttpResponseRedirect(reverse('line_form', kwargs={'no_of_lines': no_of_lines}))
else:
# It looks to me like you probably don't mean to
# use formsets here (but a form instead)
machine_form = MachineForm()
c = RequestContext(request, {
'machine_form': machine_form,
})
return render_to_response('get_no_of_lines.html', c)
def line_form(request, no_of_lines):
# You probably should validate this number (again).
# In fact, you probably need to validate first form (MachineForm).
# ...But I'm assuming it'll be valid in this example.
no_of_lines = int(no_of_lines)
LineFormSet = formset_factory(LineForm, extra=no_of_lines, formset=BaseLineFormSet)
if request.method == "POST":
formset = LineFormSet(request.POST, request.FILES)
if formset.is_valid():
pass
# Do stuff with form submission
# Redirect
else:
formset = LineFormSet()
c = RequestContext(request, {
'formset': formset,
})
return render_to_response('line_form.html', c)
urls.py:
from django.conf.urls import url, patterns
from views import get_no_of_lines, line_form
urlpatterns = patterns('',
url(r'^$', get_no_of_lines, name='get_no_of_lines'),
url(r'^line_form/(?P<no_of_lines>\d{1})$', line_form, name='line_form'),
)
get_no_of_lines.html:
<form method="POST">
{% csrf_token %}
{{ machine_form }}
</form>
line_form.html:
<form method="POST">
{% csrf_token %}
{{ formset.as_p }}
このアプローチがおそらくこれを行うための最良の方法ではないと私が言う理由は、ビューno_of_lines
に渡されることを検証する必要があるためですline_form
(4 を超える可能性があるため、ここで検証を実行し、検証ロジックを導入するのではなく、検証ロジックを導入する必要があります)。 1 か所 — フォーム)。また、最初のフォームに新しいフィールドを追加する必要がある場合は、コードを変更する必要が生じる可能性があります。したがって、フォームウィザードを調べることをお勧めします。