2013-02-15 29 views
10

我想在Django中創建一個多步表單,只在所有步驟結束時提交用於處理的數據。每一步都需要能夠訪問和顯示我們在前面步驟中輸入的數據。如何在Django中執行多步驟表單?

有沒有辦法與Django做到這一點? Django的Form-Wizard不能處理這個基本的功能。

回答

16

當然,有一種方法可以在Django中做到這一點。

一種方法是在會話中保留值直到最後提交它們。如果您返回上一步,則可以使用會話中保存的值填充表單。

隨着一些搜索,你可能會發現有人已經寫了一個應用程序,它會做你想做的,但是做你需要的並不難與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.html有一個鏈接回去step1.html。

您會在step1視圖中注意到,我從保存表單時設置的會話拉取了fn的值。您需要將前面所有步驟中的值保留到會話中。在步驟結束時,獲取值,創建對象並重定向到finished視圖,無論這可能是什麼。

這段代碼都沒有經過測試,但它應該讓你去。

+1

你知道爲什麼這個解決方案採用表嚮導不起作用? http://stackoverflow.com/questions/14860392/django-formwizards-how-to-painlessly-pass-user-entered-data-between-forms – 2013-02-15 19:14:49

+0

我實際上從來沒有在Django中使用表單嚮導,我已經自0.96以來一直在使用它,但顯然這個問題上的OP沒有找到答案。 – Brandon 2013-02-15 19:30:29

+0

那OP就是我:) – 2013-02-15 19:39:06

12

您可以通過django-formtoolsform wizard輕鬆做到這一點。一個簡單的例子就像下面這樣。

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])), 
] 
+0

指向文檔的鏈接不再有效。 – marcusshep 2015-11-10 18:31:21

+1

謝謝你的擡頭。我更新了鏈接併爲Django 1.8添加了信息。 – 2015-11-11 17:01:15

相關問題