2009-08-07 26 views
7

Estoy tratando de crear un formulario simple de varias páginas de Django usando FormWizard. Lo que el formulario debe hacer es lo siguiente:Obtener información previamente ingresada en Django FormWizard

  1. Deje que el visitante ingrese el nombre y el apellido en un formulario.
  2. Continúa en la página siguiente donde se ingresaron previamente se muestran el nombre y el apellido, también habrá un campo en esta página que permite al visitante ingresar un mensaje.
  3. El visor se llevará a la página Django done.html donde se almacenará y se mostrará toda la información.

En el paso 2, tengo problemas para encontrar la información que el visitante ingresó en el paso 1. Estoy publicando el código de los formularios y las dos plantillas utilizadas para los pasos 1 y 2 a continuación :

forms.py

from django import forms 
from django.shortcuts import render_to_response 
from django.contrib.formtools.wizard import FormWizard 

class ContactWizard(FormWizard): 
    def done(self, request, form_list): 
     return render_to_response('done.html', { 
      'form_data': [form.cleaned_data for form in form_list], 
     }) 

    def get_template(self, step): 
     return 'buydomain/templates/reg%s.html' % step 

class Form1(forms.Form): 
    firstName = forms.CharField() 
    lastName = forms.CharField() 

class Form2(forms.Form): 
    message = forms.CharField(widget=forms.Textarea) 

plantilla para la etapa 1:

{% block content %} 
<p>Step {{ step }} of {{ step_count }}</p> 
<form action="." method="post"> 
<table> 
{{ form }} 
</table> 
<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" /> 
{{ previous_fields|safe }} 
<input type="submit"> 
</form> 
{% endblock %} 

plantilla para el paso 2:

{% block content %} 
<p>Step {{ step }} of {{ step_count }}</p> 


{% comment %} 
Show values entered into Form1 here ! 
{% endcomment %} 

<form action="." method="post"> 
<table> 
{{ form }} 
</table> 
<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" /> 
{{ previous_fields|safe }} 
<input type="submit"> 
</form> 
{% endblock %} 

Pido disculpas si no tengo claro qué es lo que quiero lograr, y espero que alguien me proporcione una solución. Gracias por adelantado.

Respuesta

6

Primero algunos consejos generales: si no entiende cómo usar algo en Django, saque ese editor de texto y eche un vistazo al código. No siempre es la forma más rápida de obtener una respuesta, pero creo que rinde dividendos a largo plazo.

Intente agregar algún extra_context al segundo paso sobrescribiendo process_step en su subclase de FormWizard. Estos son los comentarios de dentro FormWizard (django 1.1):

def process_step(self, request, form, step): 
     """ 
     Hook for modifying the FormWizard's internal state, given a fully 
     validated Form object. The Form is guaranteed to have clean, valid 
     data. 

     This method should *not* modify any of that data. Rather, it might want 
     to set self.extra_context or dynamically alter self.form_list, based on 
     previously submitted forms. 

     Note that this method is called every time a page is rendered for *all* 
     submitted steps. 
     """ 
     pass 

por lo que en su propia clase ContactWizard, algo así como (NB: No corrí esto):

class ContactWizard(FormWizard): 
    def process_step(self,request,form,step): 
     if step == 1: 
      self.extra_context = {'whatever': form.whatever_you_want_from_the_form} 
      return 
     else: 
      return 
+2

¿Cómo funciona el posterior acceso clase de formulario los datos extra_context? – BozoJoe

+0

'extra_context' se pasa por' FormWizard' a la plantilla para la representación. –

+0

Aún he votado a favor esta respuesta, pero quería informar a otros que a partir de django 1.4, la firma del método process_step cambió para pasar solo en el objeto de formulario. Como dijo @bpoetz, siéntese con los documentos y léalos para encontrar una solución que funcione con sus necesidades. – avelis

3

no sé si es útil publicar aún esta solución. Sin embargo. Se puede acceder fácilmente a las necesidades entre las diferentes formas (pasos) utilizadas por el Asistente cuando le das al asistente un attrib adicional en forma de dict. Como lo siguiente:

class WizardRegistration(FormWizard): 
    def __init__(self, *args, **kwargs): 
     super(WizardRegistration, self).__init__(*args, **kwargs) 

     setattr(self, 'chosen', {}) 

Entre los pasos, puede tomar fácilmente las cosas de forma o modelo y almacenarlas hasta llegar al método done(). Almacenar un valor de forma

self.chosen['something_to_store'] = form.cleaned_data.get('a_form_value') 

o incluso obtener/cambiar/guardar un modelo

object = Model.objects.get('some_query') 

if self.chosen['object']: 
    self.chosen['object'].string = 'Something stringy' 
    self.chosen['object'].save() 
4
respuesta de

Toby Panzer no permite que la clase de formulario para acceder a los datos de contexto adicional - Sólo la plantilla de la formulario que se muestra en tiene acceso. Dicho eso, parece que es probablemente lo que necesitas. Sin embargo, si necesita que el formulario tenga acceso, lo solucioné anulando get_form_kwargs. Normalmente solo devuelve un diccionario vacío que get_form rellena, por lo que anulándolo para devolver un diccionario con los datos que necesita rellenar previamente, puede pasar kwargs a su formulario init.

def get_form_kwargs(self, step=None): 
    kwargs = {} 
    if step == '1': 
     your_data = self.get_cleaned_data_for_step('0')['your_data'] 
     kwargs.update({'your_data': your_data,}) 
    return kwargs 

Luego, en su forma método init que sólo puede hacer estallar la kwarg antes de llamar súper:

self.your_data = kwargs.pop('client', None) 
Cuestiones relacionadas