2012-09-13 15 views
7

Tengo una página web donde los usuarios pueden agregar y eliminar formularios dinámicamente, a los conjuntos de formularios django.Eliminar dinámicamente el formulario del modelo formset django

He leído Dynamically adding a form to a Django formset with Ajax, basado en que puedo agregar los formularios a un formset dinámicamente. Ahora quiero eliminar el formset dinámicamente. He visto Dynamically Delete inline formsets in Django

La forma en que quiero hacerlo es cuando el usuario hace clic en eliminar, tengo una función ajax que elimina el registro de instancia de formulario de la base de datos. Cuando devuelve mi función ajax, conservo el mismo total_form_count y initial_form_count y solo oculto el formulario html para que incluso el registro eliminado se envíe en mi POST.

Inicialmente, el juego de formularios presta sus elementos de formulario como:

#form0 
<input id="id_formprefix-0-id" type ="hidden "value="something" name="formprefix-0-id"> 
<input id="id_formprefix-0-field" value="something" type="text" name="formprefix-0-field"> 
#form1 
<input id="id_formprefix-1-id" type ="hidden "value="something" name="formprefix-1-id"> 
<input id="id_formprefix-1-field" value="something" type="text" name="formprefix-1-field"> 
#form2 
<input id="id_formprefix-2-id" type ="hidden "value="something" name="formprefix-2-id"> 
<input id="id_formprefix-2-field" value="something" type="text" name="formprefix-2-field"> 

Ahora supongamos que dinámicamente elimino forma 0, usando ajax, después de borrar mi historial, no modificar la forma recuento, por lo que el total_form_count y initial_form_count son 3.

(Si reduzco total_form_count y initial_form_count en este caso a 2, cuando llene el formset en mi vista usando datos POST, se espera que se ordene como form0 y form1. Pero en mi caso el válido los formularios son form1 y form2)

Ahora en mi opinión, hago algo como lo siguiente para guardar mi formulario.

myformset = modelformset_factory(ObjectElement,form=Object_Form, extra=0, can_delete=True) 
for form in myformset.forms: 
    print(form.instance.id) #this does not print id of deleted record, but of the first existing record in the database. 
    print(form.instance.attribute)# this prints the correct element, which was submitted by POST even for a deleted record. 
    try: 
     objectInstance = ObjectElement.objects.get(id = form.instance.id) 
     objectInstance.save() 
    except ObjectElement.DoesNotExist: 
     print("Do not save as the record has already been deleted")  

Cuando guardo mi juego de formularios sin borrar cualquier registro del ahorro funciona bien y se imprime la correcta form.instance.id. Sin embargo, si elimino una instancia de formulario con ajax y trato de guardar mi formset, el print(form.instance.id) del registro eliminado parece imprimir el primer ID disponible en la base de datos, pero no el ID que se envió por correo. (A medida que se elimina el registro, el ID no está presente en la base de datos, pero ¿debería imprimir lo que se le envió a través de POST, ¿verdad?)

Si lo hago sin el ciclo try/catch recibo el siguiente error form.errors:

<ul class="errorlist"><li>id<ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul></li></ul> 

lo que parece indicar que no está aceptando la forma correcta identificación formar el mensaje enviado por el registro eliminado.

¿Alguien tiene alguna idea de lo que me falta aquí? O una mejor manera de hacer esto.

Cómo vamos eliminando de forma dinámica sobre las formas de juegos de formularios, ya que parece que el orden de las formas debe ser secuencial ..

Gracias de antemano !! Cualquier ayuda es apreciada.

Respuesta

9

Para aquellos que encuentren este problema, esta podría ser una posible solución Puedo eliminar dinámicamente mi formulario de formset de la siguiente manera.

Así que el formulario HTML inicial parece

#form0 
<input id="id_formprefix-0-id" type ="hidden "value="something" name="formprefix-0-id"> 
<input id="id_formprefix-0-field" value="something" type="text" name="formprefix-0-field"> 
#form1 
<input id="id_formprefix-1-id" type ="hidden "value="something" name="formprefix-1-id"> 
<input id="id_formprefix-1-field" value="something" type="text" name="formprefix-1-field"> 
#form2 
<input id="id_formprefix-2-id" type ="hidden "value="something" name="formprefix-2-id"> 
<input id="id_formprefix-2-field" value="something" type="text" name="formprefix-2-field"> 

Ahora supongamos elimino form0 y registros Form1 en mi base de datos usando ajax. Cuando envío el formulario, el formset no se validará, porque espera que los formularios estén en orden, y solo tengo el formulario 2 restante en la base de datos (eliminé los dos superiores).Los errores de Formset con "Seleccione una opción válida" como se describe en la pregunta.

Así que después de eliminar los formularios dinámicamente, cuando mi ajax vuelve, no cambio el total_form_count, (https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#understanding-the-managementform) pero marco el formulario como eliminado en mi html, y simplemente oculto el formulario. Ahora cuando el formset se envía utilizando POST, también envía el formulario eliminado, pero se marca como eliminado (https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#can-delete)

Ahora en la vista, primero filtrar los formularios que se han eliminado, y solo procesar los formularios que todavía permanecer como sigue

marked_for_delete = formset.deleted_forms 
    for form in formset.forms: 
     #Filtering out the deleted records, as the formset will not validate, for deleted records 
     # if we use form.instance.id or form.initial['id'] below it does not work. 
     #for some reason it returns the id of the first available record in the data base. 
     #form['id'].value(), gives us the id of the deleted element we are looking for 
     if form['id'].value() not in [deleted_record['id'].value() for deleted_record in marked_for_delete]:  
      if form.is_valid(): 
       pass 
       # save the form 
      else: 
       pass 
       # error message 
+0

¿cómo exactamente marca cada formulario para eliminar? – amchugh89

+0

@ amchugh89 Bueno, entonces creo que miré [esto] (https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#can-delete). Pero [las versiones más recientes] (https://docs.djangoproject.com/en/1.7/topics/forms/formsets/#understanding-the-managementform) especifican que puede marcar para eliminar incluyendo 'form - # - DELETE' en la publicación datos. – akotian

Cuestiones relacionadas