2013-02-15 13 views
10

Mi piacerebbe creare una forma a più passaggi in Django che invia i dati solo per l'elaborazione alla fine di tutti i passaggi. Ogni passaggio deve essere in grado di accedere e visualizzare i dati inseriti nei passaggi precedenti.Come fare una forma multi-step in Django?

C'è un modo per farlo con Django? La procedura guidata di Django non è in grado di gestire questa funzionalità di base.

risposta

16

Ovviamente c'è un modo per farlo in Django.

Un modo è quello di mantenere i valori in sessione finché non li si invia alla fine. È possibile popolare i moduli utilizzando i valori trattenuti in sessione se si ritorna al passaggio precedente.

Con un po 'di ricerca, potresti trovare un'app che qualcuno ha già scritto che farà ciò che vuoi, ma fare ciò che ti serve non è difficile da fare con Django o qualsiasi altro framework.

esempio, ignorando le istruzioni 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}) 

Supponiamo che step2.html ha un link per tornare alla step1.html.

Nella vista step1 notificherò il valore per fn dalla sessione impostata al momento del salvataggio del modulo. Dovresti mantenere i valori di tutti i passaggi precedenti nella sessione. Alla fine della procedura, acquisisci i valori, crea i tuoi oggetti e reindirizza a una vista finished, qualunque essa sia.

Nessuno di questo codice è stato testato, ma dovrebbe farti andare.

+1

Sapete perché questa soluzione utilizzando il modulo Wizard non funziona? http://stackoverflow.com/questions/14860392/django-formwizards-how-to-painlessly-pass-user-entered-data-between-forms –

+0

In realtà non ho mai usato il wizard dei form in Django, e ho ha lavorato con esso dal 0.96, ma a quanto pare l'OP su quella domanda non ha mai trovato la risposta. – Brandon

+0

Questo OP ero io :) –

12

È possibile farlo facilmente con lo form wizard di django-formtools. Un semplice esempio potrebbe essere simile al seguente.

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

Il collegamento ai documenti non funziona più. – marcusshep

+1

Grazie per l'avviso. Ho aggiornato il collegamento e aggiunto informazioni per Django 1.8. –

Problemi correlati