django django-forms django-views django-formwizard

django - El estado SessionWizardView solo se guarda en el formulario final, done() no se ejecuta



django-forms django-views (2)

El paso 1 en la documentación que se encuentra aquí es la respuesta. Declara lo siguiente.

El usuario visita la primera página del asistente, rellena el formulario y lo envía.

La clave aquí es el "enviar". No se guarda ninguna validación de formulario o estado a menos que se envíe el formulario. El uso de wizard_goto_step para next / previous / jump no envía el formulario, no valida el formulario y no guarda el formulario en la sesión / cookie (dependiendo de cuál elija).

Ahora es obvio, pero sigo pensando que esto es engañoso para los posibles usuarios finales del asistente de formularios. Es bastante fácil para mí reemplazar el wizard_goto_step con un envío real cuando se avanza al siguiente paso, pero cuando los usuarios ingresan algunos datos en un formulario y luego eligen volver a visitar otro paso, se pierden todos sus datos en ese paso.

Parece que los datos del formulario se deben guardar incluso cuando estén incompletos. Mi intención es guardar estos datos manualmente usando la función storage.set_step_data (), ya que todos los pasos del formulario se vuelven a validar en el procesamiento final de todos modos. Incluso si un usuario llena los datos incorrectos en un paso, se los redireccionará al paso con los datos faltantes al final. Esto se siente como un mejor comportamiento que limpiar a ciegas los datos del usuario en un paso cuando visitan un paso anterior.

Tengo varios formularios que he agregado a un asistente, pero el estado de formulario solo se mantiene para el paso final, y done () no se ejecuta.

He creado lo siguiente, muy basado en los ejemplos en la documentación de django, para tratar de llegar al fondo de esto. Parece que el paso final es el único que salva el estado cuando se mueve entre los pasos.

class OneForm( Form ): field_one = forms.CharField(label=''1'', max_length=100) field_two = forms.CharField(label=''2'', max_length=100) field_three = forms.CharField(label=''3'', max_length=100) class TwoForm( Form ): field_one = forms.CharField(label=''4'', max_length=100) field_two = forms.CharField(label=''5'', max_length=100) field_three = forms.CharField(label=''6'', max_length=100) TEST_WIZARD_FORMS = [ ("one", OneForm), ("two", TwoForm), ] TEST_TEMPLATES = { ''one'': ''tour/one.html'', ''two'': ''tour/two.html'', } class TestWizardView( SessionWizardView ): form_list = TEST_WIZARD_FORMS def done(self, form_list, **kwargs): print(''done executed'') return reverse(''home'') def get_template_names(self): return [TEST_TEMPLATES[self.steps.current]]

y esto para plantillas (tanto one.html como two.html son idénticas)

<html> <body> <p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p> <form action="" method="post">{% csrf_token %} <table> {{ wizard.management_form }} {% if wizard.form.forms %} {{ wizard.form.management_form }} {{ wizard.form.non_field_errors }} {{ wizard.form.errors }} {% for form in wizard.form.forms %} {{ form }} {% endfor %} {% else %} {{ wizard.form }} {% endif %} </table> {% if wizard.steps.prev %} <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">"first step"</button> <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">"prev step"</button> {% endif %} <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.next }}">"next step"</button> <input type="submit" value="submit"/> </form> </body> </html>

Si ingreso datos en el paso 1, continúe con el paso 2 e ingrese datos, luego regrese al paso 1, el primer paso no tiene datos guardados y no se muestran errores de formulario. Cuando presiono siguiente para regresar al paso 2, los datos del paso 2 aún están presentes. Poner intencionalmente datos inválidos en el paso 1 me ha mostrado que tampoco valida el formulario, ya que el asistente continúa con el paso 2 sin mostrar errores.

Cuando envío el formulario, done () no se ejecuta. Esto tiene sentido si solo el último paso es realmente exitoso, pero no ver errores en el paso 1 me ha desconcertado.

¿Por qué no se mantienen los datos del formulario excepto en el formulario final? ¿Por qué el último paso es el único que realmente valida los datos del formulario? ¿Por qué no se ejecuta?

Actualización: parece que la validación del formulario está sucediendo después de todo, y lo veo teniendo éxito mediante la impresión de información relevante en la función de publicación, pero hecho () todavía no parece ejecutarse.

Gracias.


Sin duda es un error. Tienes que eliminar las siguientes líneas de código de

/ formtools / wizard / views.py

# walk through the form list and try to validate the data again. # for form_key in self.get_form_list(): # form_obj = self.get_form(step=form_key, # data=self.storage.get_step_data(form_key), # files=self.storage.get_step_files(form_key)) # if not form_obj.is_valid(): # return self.render_revalidation_failure(form_key, # form_obj, # **kwargs) # final_forms[form_key] = form_obj

En realidad, no entiendo el motivo de este código. Todos los formularios fueron validados después de su envío. No veo ninguna razón para validarlos de nuevo?

Esta validación falla por algún motivo desconocido, y es por eso que nunca se llama a la rutina realizada más adelante.