2010-11-12 14 views
6

Ho una webapp django con più utenti che accedono e compilano un modulo.Django Salva progresso incompleto sul modulo

Alcuni utenti possono iniziare a compilare un modulo e mancano alcuni dati richiesti (ad esempio un numero di concessione) necessari per convalidare il modulo (e prima di poter iniziare a lavorarci). Voglio che siano in grado di compilare il modulo e avere un'opzione per salvare le informazioni parziali (quindi un altro giorno possono effettuare di nuovo il login e completarlo) o inviare le informazioni complete in fase di convalida.

Attualmente sto utilizzando ModelForm per tutti i moduli che utilizzo e il Modello ha vincoli per garantire dati validi (ad esempio, il numero di concessione deve essere univoco). Tuttavia, voglio che siano in grado di salvare questi dati intermedi senza subire alcuna convalida.

La soluzione che ho pensato sembra piuttosto inelegante e poco django-ey: creare un pulsante "Save forma parziale" che salva il dizionario POST lo converte in un file di shelf e creare un modello di "SavedPartialForm" che collega l'utente a forme parziali salvate nello scaffale. Questo sembra ragionevole? C'è un modo migliore per salvare il POST dict direttamente nel db? O è un modulo aggiuntivo che fa questo salvataggio parziale di un modulo (che sembra essere un'attività abbastanza comune con webforms)?

La mia più grande preoccupazione per il mio metodo è che alla fine posso essere in grado di eseguire questo modulo: il salvataggio automatico (ad esempio ogni 10 minuti) in qualche metodo Ajax/jQuery senza effettivamente premere un pulsante e inviare la richiesta POST (ad es. l'utente non viene reindirizzato dalla pagina quando viene attivato il salvataggio automatico). Non sono così familiare con jquery e mi chiedo se sarebbe possibile farlo.

+0

sei riuscito a farlo funzionare? puoi fornire una risposta dettagliata su come farlo. Questo sarà molto utile per altri sviluppatori .. –

risposta

5

C'è una buona soluzione in Pro Django by Marty Alchin. In poche parole, si crea un altro modello che contiene un hash del modulo, il campo modulo e il valore salvato. Quando riprendi, devi solo caricare il modulo in base al suo hash.

1

Il problema è che si dispone di più moduli.

Parziale. Incompleta. Completare. Pronto per questo. Pronto per quello.

In effetti, si dispone di un modulo per fase di un flusso di lavoro.

Niente di sbagliato in tutto questo.

  1. Scopri dove sei nel flusso di lavoro.

  2. Compilare e presentare il modulo per la fase successiva.

Le forme possono ereditare l'una dall'altra per salvare ripetendo i metodi di convalida.

+0

Grazie. Questo è utile e un buon modo di guardarlo. Mi chiedo ancora se questo potrebbe essere incompatibile con il salvataggio automatico di moduli parziali/incompleti ogni dieci minuti circa con una specie di codice jQuery. –

+0

@jimbob: mai. Il punto è avere una forma che corrisponda allo stato attuale del flusso di lavoro. Se non riescono a compilare i dati corretti per la loro fase del flusso di lavoro, il modulo non è valido. Se hanno riempito abbastanza per questa fase, il modulo è valido. Se vogliono riempire di più, devi passare attraverso i moduli pertinenti fino a raggiungere quello che hanno inserito. –

2

prima di risparmio:

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

poi:

form.save() 
0

Inserire il seguente nella vostra forma __init__

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

Ad esempio:

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

quindi chiamare:

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

Tuttavia è necessario assicurarsi che il metodo di clean() in grado di gestire tutti gli attributi mancanti condizionale controllando se esistono in cleaned_data. Ad esempio, se un'altra convalida del campo modulo si basa su customer_id ma il modulo parziale non ne ha specificato uno, quindi customer_id non si troverà in clean_data.

Se questo è per un modulo modello, è possibile verificare se il valore era in cleaned_data e fallback su instance.field se mancava, ad esempio;

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 

ricordare che il nuovo valore valore sarà quasi certamente non essere nello stesso formato come il vecchio valore, ad esempio customer_id potrebbe effettivamente essere un RelatedField nell'istanza modello, ma un pk int sui dati del modulo. Ancora una volta, dovrai gestire queste differenze di tipo all'interno del tuo clean.

Questa è un'area in cui le forme di Django mancano davvero tristemente.