2010-11-12 15 views
6

Tengo una aplicación web django con usuarios múltiples que inician sesión y completan un formulario.Django Guardar progreso incompleto en el formulario

Algunos usuarios pueden comenzar a completar un formulario y carecen de algunos datos necesarios (por ejemplo, un número de concesión) necesarios para validar el formulario (y antes de que podamos comenzar a trabajar en él). Quiero que puedan completar el formulario y tener la opción de guardar la información parcial (para que otro día puedan volver a iniciar sesión y completarla) o enviar la información completa en proceso de validación.

Actualmente estoy usando ModelForm para todos los formularios que uso, y el modelo tiene restricciones para garantizar la validez de los datos (por ejemplo, el # de la concesión tiene que ser único). Sin embargo, quiero que puedan guardar esta información intermedia sin someterse a ninguna validación.

La solución que he pensado parece bastante poco elegante y poco dinámica: crear un botón "Guardar formulario parcial" que guarda el diccionario POST lo convierte en un archivo shelf y crea un modelo "SavedPartialForm" que conecta al usuario a formas parciales guardadas en el estante. ¿Esto parece sensato? ¿Hay una mejor manera de guardar el dict de POST directamente en el db? ¿O es un módulo complementario que realiza este guardado parcial de un formulario (que parece ser una actividad bastante común con formularios web)?

Mi mayor preocupación con mi método es que eventualmente pueda hacer este formulario-autoguardar automáticamente (digamos cada 10 minutos) en algún método ajax/jquery sin presionar un botón y enviar la solicitud POST (por ejemplo, el usuario no se redirige fuera de la página cuando se activa el autoguardado). No estoy tan familiarizado con jquery y me pregunto si sería posible hacer esto.

+0

¿Pudiste hacerlo funcionar? puede proporcionar una respuesta detallada de cómo hacerlo. Eso será muy útil para otros desarrolladores. –

Respuesta

5

Hay una buena solución en Pro Django by Marty Alchin. En pocas palabras, crea otro modelo que contiene un hash del formulario, el campo de formulario y el valor guardado. Al reanudar, solo carga según el formulario de acuerdo con su hash.

1

El problema es que tiene múltiples formularios.

Parcial. Incompleto. Completar. Listo para esto. Listo para eso

De hecho, tiene un Formulario por etapa de un flujo de trabajo.

Nada de malo en esto.

  1. Averigüe en qué parte del flujo de trabajo se encuentra.

  2. Rellene y presente el formulario para la siguiente etapa.

Los formularios pueden heredarse entre sí para guardar métodos de validación que se repiten.

+0

Gracias. Esto es útil y una buena forma de verlo. Todavía me pregunto si esto puede ser incompatible con el auto-guardado de formas parciales/incompletas cada diez minutos más o menos con algún tipo de código jQuery. –

+0

@jimbob: Nunca. El punto es tener un formulario que coincida con la etapa actual del flujo de trabajo. Si no pueden completar los datos adecuados para su etapa del flujo de trabajo, el formulario no es válido. Si se han llenado lo suficiente para esta etapa, el formulario es válido. Si desean completar más, debe pasar por los formularios pertinentes hasta que se pongan al día con lo que ingresaron. –

2

antes de guardar:

for field in form.fields: 
    form.fields[field].required = False 

a continuación:

form.save() 
0

Lugar lo siguiente en su forma __init__

for field in form.fields: 
    form.fields[field].required = False 

Por ejemplo:

class MySexyForm(Form): 
    def __init__(self, *args, **kwargs): 
     super(MySexyForm, self).__init__(*args, **kwargs) 
     for field in self.fields: 
      self.fields[field].required = False 

luego llamar a:

form = MySexyForm(...) 
form.save() 

Sin embargo, usted tiene que asegurarse de que su método de clean() puede manejar cualquiera de los atributos que faltan mediante la comprobación condicional si existen en cleaned_data. Por ejemplo, si otra validación de campo de formulario se basa en customer_id pero su forma parcial no ha especificado una, entonces customer_id no estaría en datos_limpios.

Si se trata de un formulario de modelo, puede verificar si el valor estaba en cleaned_data, y recurrir a instance.field si faltaba, por ejemplo;

def clean(self): 
    inst = self.instance 
    customer_id_new = self.cleaned_data.get('customer_id', None) 
    customer_id_old = getattr(self.instance, 'customer_id') if inst else None 
    customer_id = customer_id_new if customer_id_new else customer_id_old 

Recuerde que el valor nuevo valor es casi seguro que no estará en el mismo formato que el antiguo valor, por ejemplo customer_id podría ser en realidad un RelatedField en la instancia de modelo, sino un pk int en los datos del formulario. Nuevamente, deberá manejar estas diferencias de tipo dentro de su limpieza.

Esta es un área donde las Formas de Django realmente carecen tristemente.

Cuestiones relacionadas