2015-05-29 20 views
5

Esiste una reale mancanza di documentazione su come lavorare con FieldList di WTForms. Quindi grazie a internet sono stato in grado di incidere insieme il seguente:Come si può compilare una FieldList di WTForms dopo il blocco validate_on_submit()?

Forma:

class BranchForm(Form): 
    name = StringField('Name', validators = [Required()]) 
    equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int, 
     choices = [(x.id, x.name) for x in Equipment.query.all()])) 
    mod = FieldList(StringField('Method of Delivery', validators = [Optional()])) 

Vista:

def edit_branch(id): 
    branch = Branch.query.filter_by(id=id).first() 

    #populate data_in to be used by BranchForm 
    data_in = [] 
    for eq_obj in branch.equipment_assoc: 
     data_in.append(('equipment', eq_obj.equipment.id)) 
     data_in.append(('mod', eq_obj.mod)) 

    editform = BranchForm(data=MultiDict(data_in)) 

    if editform.validate_on_submit(): 
     branch.name = editform.name.data 

     db.session.add(branch) 
     db.session.commit() 

     return redirect('/admin/branches/' + str(branch.id)) 

    editform.name.data = branch.name 

    return render_template("branch_edit.html", 
     title="Edit Branch", 
     branch = branch, 
     editform = editform) 

Cosa mi ha gettato via è che tutto il resto che ho Ho usato un modulo WTForm e popolato i campi con i dati del mio db (come per i moduli di modifica), ho dovuto compilare questi campi modulo dopo il blocco form.validate_on_submit(), perché altrimenti, il modulo non si aggiornerà mai come viene inviato viene immediatamente sovrascritto.

Vedere "editform.name.data = branch.name" (questo è il modo che ho sempre fatto)

Da ogni esempio che ho trovato in rete a popolare un FieldList, a quanto pare deve essere fatto durante l'istanziazione, ma il modulo deve essere istanziato prima di validate_on_submit() e perché validate_on_submit() è un metodo dell'oggetto form.

Vedere "EditForm = BranchForm (data = MultiDict (DATA_IN))" (questo è il modo che ho visto FieldLists popolate in tutti gli esempi che ho visto.)

Come posso andare sulla compilazione del mio modulo con i suoi elenchi di campi?

risposta

0

OK, quindi un amico mi ha aiutato a capire questo. Ecco quello che ho finito con:

Forma:

class BranchForm(Form): 
    name = StringField('Name', validators = [Required()]) 
    equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int, 
     choices = [(x.id, x.name) for x in Equipment.query.all()])) 
    mod = FieldList(StringField('Method of Delivery', validators = [Optional()])) 

    def populate_assoc(self, branch_obj): 
     i = 0 
     branch_obj.name = self.name.data 
     for assoc_obj in branch_obj.equipment_assoc: 
      assoc_obj.equipment_id = self.equipment[i].data 
      assoc_obj.mod = self.mod[i].data 
      i += 1 

Vista:

def edit_branch(id): 
    branch = Branch.query.filter_by(id=id).first() 

    if request.method == 'POST': 
     editform = BranchForm() 

     if editform.validate_on_submit(): 
      editform.populate_assoc(branch) 

      db.session.add(branch) 
      db.session.commit() 

      return redirect('/admin/branches/' + str(branch.id)) 

    #populate data_in to be used 
    data_in = [] 
    for eq_obj in branch.equipment_assoc: 
     data_in.append(('equipment', eq_obj.equipment.id)) 
     data_in.append(('mod', eq_obj.mod)) 

    editform = BranchForm(data=MultiDict(data_in)) 
    editform.name.data = branch.name 

    return render_template("branch_edit.html", 
     title="Edit Branch", 
     branch = branch, 
     editform = editform) 

Il trucco era veramente fare un passo lontano da utilizzando form.validate_on_submit() come la mia separazione logica, poiché si basa sull'oggetto modulo. La sua idea era di usare lo se request.method == 'POST': per questo scopo. In questo modo posso istanziare la mia forma in due modi diversi. Uno viene popolato per la visualizzazione, l'altro viene solo istanziato se il metodo di richiesta è POST, conservando così le informazioni inviate nel modulo.

Per finire il lavoro ho aggiunto il metodo populate_assoc alla mia classe modulo in modo da poter facilmente inserire le informazioni dal modulo nel mio modello di associazione.

0

WtForms ha un metodo populate_obj(). Forse è quello che cerchi?

def edit_branch(id): 
    branch = Branch.query.filter_by(id=id).first() 
    editform = BranchForm(obj=branch) 
    if editform.validate_on_submit(): 
     editform.populate_obj(branch) 

     db.session.commit() 

     return redirect('/admin/branches/' + str(branch.id)) 

    return render_template("branch_edit.html", 
     title="Edit Branch", 
     branch = branch, 
     editform = editform) 
+0

Grazie per il suggerimento, ma credo che sia la direzione opposta rispetto a quella che sto cercando. Sto cercando di popolare il mio modulo con i dati del mio oggetto modello, invece di popolare il mio oggetto modello con i dati del mio modulo. – Chockomonkey

+1

Penso che questa riga nella risposta faccia ciò: 'editform = BranchForm (obj = branch)' –

+0

@PauloBu Sì, ma funziona solo prima del se validate_on_submit(): block. Sto cercando un modo per popolare BranchForm dopo l'istanziazione. – Chockomonkey