Django Guarda Progreso Incompleto en Forma

Tengo una aplicación web de django con varios usuarios que inician sesión y completan un formulario.

Algunos usuarios pueden comenzar a completar un formulario y carecen de algunos datos necesarios (por ejemplo, un número de subvención) necesarios para validar el formulario (y antes de que podamos comenzar a trabajar en él). Quiero que puedan completar el formulario y tener una opción para 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 asegurar que los datos sean válidos (por ejemplo, el número de concesión tiene que ser único). Sin embargo, quiero que puedan guardar estos datos intermedios sin someterse a ninguna validación.

La solución que he pensado me parece poco elegante y no django-ey: crear un botón “Guardar formulario parcial” que guarda el diccionario de POST, lo convierte en un archivo de estante y crea un modelo “SavedPartialForm” que conecta al usuario con formularios parciales guardados en el estante ¿Esto parece sensato? ¿Hay una mejor manera de guardar el dictado POST directamente en la db? ¿O es un módulo complementario que realiza este guardado parcial de un formulario (que parece ser una actividad bastante común con los formularios web)?

Mi mayor preocupación con mi método es que eventualmente podré hacer esto automáticamente de forma automática (por ejemplo, cada 10 minutos) en algún método ajax / jquery sin presionar un botón y enviar la solicitud POST (por ejemplo, para que el usuario no esté t redirigido fuera de la página cuando se activa el guardado automático). No estoy familiarizado con jQuery y me pregunto si sería posible hacer esto.

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

antes de guardar:

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

entonces:

 form.save() 

El problema es que tienes múltiples formularios.

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

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

No hay nada malo con esto en absoluto.

  1. Averigua en qué parte del flujo de trabajo estás.

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

Los formularios pueden heredarse unos de otros para guardar los métodos de validación que se repiten.

Coloque lo siguiente en su formulario __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 llame:

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

Sin embargo, deberá asegurarse de que su método clean() pueda manejar cualquier atributo faltante verificando condicionalmente si existen en clean_data. Por ejemplo, si la validación de otro campo de formulario se basa en customer_id pero su formulario parcial no ha especificado uno, entonces customer_id no estaría en clean_data.

Si esto es para un formulario modelo, podría verificar si el valor estaba en cleaned_data , y cleaned_data 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 valor nuevo probablemente no tendrá el mismo formato que el valor anterior, por ejemplo, customer_id podría ser un RelatedField en la instancia del modelo pero un pk int en los datos del formulario. Una vez más, deberá manejar estas diferencias de tipo dentro de su limpieza.

Esta es un área en la que Django Forms realmente carece de tristeza.