2012-09-13 12 views
7

Ho una pagina Web in cui gli utenti possono aggiungere e cancellare moduli dinamicamente, ai formset di Django.Elimina dinamicamente dal formset del modello django

Ho letto Dynamically adding a form to a Django formset with Ajax, in base al quale posso aggiungere dinamicamente i moduli a un formset. Ora voglio eliminare il formset in modo dinamico. Ho visto Dynamically Delete inline formsets in Django

Il modo in cui voglio farlo è quando l'utente fa clic su Elimina, ho una funzione Ajax che elimina il record dell'istanza del modulo dal database. Quando la funzione ajax viene restituita, mantengo lo stesso totale_form_count e initial_form_count e solo il nascondi il modulo html in modo che anche il record eliminato venga inviato nel mio POST.

Inizialmente il formset rende i suoi elementi del modulo come:

#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"> 

Ora supponiamo che io dinamicamente cancellare forma 0, utilizzando AJAX, dopo che il mio record viene eliminato, non cambio i conteggi di forma, in modo che il total_form_count e initial_form_count sono 3.

(Se riduco total_form_count e initial_form_count in questo caso a 2, quando popolo il formset nella mia vista utilizzando i dati POST, è previsto che sia ordinato come form0 e form1. Ma nel mio caso il valido le forme sono form1 e form2)

Ora, a mio avviso, faccio qualcosa di simile al seguente per salvare il mio modulo.

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")  

Quando ho salvare il mio formset senza eliminare alcun record risparmio funziona bene e la corretta form.instance.id viene stampato. Tuttavia, se elimino un'istanza di modulo utilizzando ajax e quindi provo a salvare il mio formset, lo print(form.instance.id) per il record eliminato sembra stampare il primo ID disponibile nel database, ma non l'ID inviato per posta. (Come il record è cancellato, l'id non è presente nel database, ma dovrebbe stampare ciò che è stato inviato tramite il POST giusto?)

Se lo faccio senza il ciclo try/catch ottengo il seguente errore da 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> 

che sembra indicare che essa non accetta la forma corretta ID formare il palo presentato per il record eliminato.

Qualcuno ha idea di cosa mi manca qui? O un modo migliore per farlo.

Come andiamo circa dinamicamente l'eliminazione di forme di formsets, come sembra che l'ordine delle forme deve essere sequenziale ..

Grazie in anticipo !! Qualsiasi aiuto è apprezzato.

risposta

9

Per coloro che si imbattono in questo problema questa potrebbe essere una soluzione possibile Sono in grado di eliminare in modo dinamico il mio modulo da formset come segue.

Così il form html iniziale sembra

#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"> 

Ora supponiamo elimino form0 e record Form1 dalla mia base di dati utilizzando AJAX. Quando invio il modulo, il formset non verrà convalidato, perché si aspetta che i moduli siano in ordine, e ho solo il modulo 2 rimasto nel database (ho cancellato i primi due).Formset errori con "Seleziona una scelta valida" come descritto nella domanda.

Quindi, dopo aver eliminato i moduli dinamicamente, quando viene restituita la mia ajax, non cambio lo total_form_count, (https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#understanding-the-managementform) ma contrassegno il modulo come eliminato nel mio html e nascondo semplicemente il modulo. Ora, quando il formset viene inviato utilizzando il POST, invia anche il modulo eliminato, ma contrassegnato come eliminato (https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#can-delete)

Ora nella vista, prima rimuovo i moduli che sono stati eliminati e elaboriamo solo i moduli che ancora rimangono come segue

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

in che modo si contrassegna ciascun modulo per l'eliminazione? – amchugh89

+0

@ amchugh89 Bene, allora credo di aver guardato [questo] (https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#can-delete). Ma [nuove versioni] (https://docs.djangoproject.com/en/1.7/topics/forms/formsets/#understanding-the-managementform) specifica che puoi contrassegnare per la cancellazione includendo 'form - # - DELETE' in post dati. – akotian

Problemi correlati