33

I would like to create a mutli-step form in Django that only submits the data for processing at the end of all the steps. Each step needs to be able to access and display data that we entered in previous step(s).

Is there a way to do this with Django? Django's Form-Wizard can't handle this basic functionality.

4

2 に答える 2

36

もちろん、Django でこれを行う方法があります。

1 つの方法は、値を最後に送信するまでセッションで値を保持することです。前のステップに戻ると、セッションで保持されている値を使用してフォームに入力できます。

いくらか検索すると、誰かが既に作成したアプリケーションで目的の機能を実行できるものを見つけることができますが、Django やその他のフレームワークを使用すると、必要なことを実行するのは難しくありません。

import ステートメントを無視する例:

#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.htmlstep1.html に戻るためのリンクがあると仮定します。

ビューで、フォームが保存されたときに設定されたセッションからstep1値を取得していることに気付くでしょう。fn前のすべてのステップの値をセッションに永続化する必要があります。ステップの最後で、値を取得し、オブジェクトを作成して、finishedビューにリダイレクトします。

このコードはどれもテストされていませんが、うまくいくはずです。

于 2013-02-15T19:12:52.497 に答える
22

これは、 django-formtoolsのフォーム ウィザードを使用して簡単に行うことができます。簡単な例は次のようになります。

フォーム.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)

ビュー.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])),
]
于 2014-04-09T18:58:11.980 に答える