2015-05-29 7 views
5

Es fehlt wirklich an Dokumentation darüber, wie man mit der Feldliste von WTForms arbeitet. So dank dem Internet Ich habe in der Lage zusammen folgendes zu hacken:Wie können Sie eine WTForms-Feldliste nach dem validate_on_submit() - Block auffüllen?

Form:

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()])) 

Ausblick:

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) 

was mich abzuwerfen ist, dass überall sonst, dass ich nutzte ein WTForm-Formular und füllte die Felder mit Daten aus meiner Datenbank (wie für Bearbeitungsformulare), ich musste diese Formularfelder nach dem form.validate_on_submit() - Block ausfüllen, denn wenn nicht, dann wird das Formular niemals als was auch immer aktualisiert gesendet wird, wird sofort überschrieben.

Siehe „editform.name.data = branch.name“ (das ist, wie ich es immer getan habe)

Von jedem Beispiel habe ich festgestellt Online über einen Fieldlist bevölkert, ist es offensichtlich muss während der Instantiierung ausgeführt werden, aber das Formular muss auch vor validate_on_submit() instanziiert werden, da validate_on_submit() eine Methode des Formularobjekts ist.

Siehe "EditForm = BranchForm (data = MultiDict (Daten_Ein))" (das ist, wie ich habe FieldLists in allen Beispielen bevölkert gesehen, die ich je gesehen habe.)

Wie kann ich gehen über das Füllen meines Formulars mit seinen Feldlisten?

Antwort

0

In Ordnung, also half mir ein Kumpel, dieses herauszufinden. Hier ist, was ich am Ende mit:

Form:

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 

Ausblick:

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) 

Der Trick war wirklich zu Schritt weg von der Verwendung form.validate_on_submit() als meine Logik Separator, da es auf dem Formularobjekt beruht. Seine Idee war, die if request.method == 'POST': für diesen Zweck zu verwenden. Auf diese Weise kann ich meine Form auf zwei verschiedene Arten instanziieren. Einer wird für die Anzeige ausgefüllt, der andere wird nur instanziiert, wenn die Anfrage-Methode POST ist und somit die im Formular übermittelten Informationen beibehält.

Um den Job zu beenden, habe ich die populate_assoc-Methode zu meiner Formularklasse hinzugefügt, sodass ich die Informationen aus dem Formular problemlos in mein Verknüpfungsmodell einfügen kann.

0

WtForms hat eine populate_obj() -Methode. Vielleicht ist es das, wonach Sie suchen?

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

Danke für den Vorschlag, aber ich glaube, das ist die umgekehrte Richtung als ich danach bin. Ich versuche, mein Formular mit Daten aus meinem Modellobjekt zu füllen, anstatt mein Modellobjekt mit Daten aus meinem Formular zu füllen. – Chockomonkey

+1

Ich denke, diese Zeile in der Antwort tut das: 'editform = BranchForm (obj = Zweig)' –

+0

@PauloBu Ja, tut es, aber das funktioniert nur vor dem if validate_on_submit(): Block. Ich bin auf der Suche nach einer Möglichkeit, BranchForm nach der Instanziierung zu füllen. – Chockomonkey