Как сделать многошаговую форму в Django?
Я хотел бы создать многошаговую форму в Django, которая предоставляет данные для обработки только в конце всех шагов. Каждый шаг должен иметь возможность доступа и отображения данных, которые мы ввели на предыдущем шаге (ах).
Есть ли способ сделать это с Джанго? Мастер форм Django не может справиться с этой основной функциональностью.
3 ответа
Конечно, есть способ сделать это в Django.
Одним из способов является сохранение ваших значений в сессии, пока вы не отправите их в конце. Вы можете заполнить свои формы, используя значения, хранящиеся в сеансе, если вы вернетесь к предыдущему шагу.
При некотором поиске вы можете найти приложение, которое кто-то уже написал, которое будет делать то, что вы хотите, но делать то, что вам нужно, нетрудно с Django или любым другим фреймворком.
Пример, игнорирующий операторы импорта:
#models/forms
class Person(models.Model):
fn = models.CharField(max_length=40)
class Pet(models.Model):
owner = models.ForeignKey(Person)
name = models.CharField(max_length=40)
class PersonForm(forms.ModelForm):
class Meta:
model = Person
class PetForm(forms.ModelForm):
class Meta:
model = Pet
exclude = ('owner',)
#views
def step1(request):
initial={'fn': request.session.get('fn', None)}
form = PersonForm(request.POST or None, initial=initial)
if request.method == 'POST':
if form.is_valid():
request.session['fn'] = form.cleaned_data['fn']
return HttpResponseRedirect(reverse('step2'))
return render(request, 'step1.html', {'form': form})
def step2(request):
form = PetForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
pet = form.save(commit=False)
person = Person.objects.create(fn=request.session['fn'])
pet.owner = person
pet.save()
return HttpResponseRedirect(reverse('finished'))
return render(request, 'step2.html', {'form': form})
Мы будем предполагать, что step2.html
есть ссылка, чтобы вернуться к step1.html.
Вы заметите в step1
посмотреть я тяну значение для fn
из сеанса, который был установлен при сохранении формы. Вам нужно будет сохранить значения всех предыдущих шагов в сеансе. В конце шагов захватите значения, создайте свои объекты и перенаправьте на finished
вид, что бы это ни было.
Ни один из этого кода не был протестирован, но он должен помочь вам.
Вы можете легко сделать это с помощью мастера форм django-formtools. Простым примером будет что-то вроде следующего.
forms.py
from django import forms
class ContactForm1(forms.Form):
subject = forms.CharField(max_length=100)
sender = forms.EmailField()
class ContactForm2(forms.Form):
message = forms.CharField(widget=forms.Textarea)
views.py
from django.shortcuts import redirect
from formtools.wizard.views import SessionWizardView
class ContactWizard(SessionWizardView):
def done(self, form_list, **kwargs):
do_something_with_the_form_data(form_list)
return redirect('/page-to-redirect-to-when-done/')
urls.py
from django.conf.urls import url
from forms import ContactForm1, ContactForm2
from views import ContactWizard
urlpatterns = [
url(r'^contact/$', ContactWizard.as_view([ContactForm1, ContactForm2])),
]
print(form.errors.items)
прямо перед проверкой
if form.is_valid()