Как сделать многошаговую форму в 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()

Другие вопросы по тегам