WTForms - Datenübergabe Formular

Django, Flask, Bottle, WSGI, CGI…
Antworten
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Hallo,
ich habe eine Frage zur Benutzung von WTForms, genauer wie man dem Formular Daten übergeben kann. Genauer gesagt, geht es um ein modifiziertes SelectMultipleField:

Code: Alles auswählen

class IterableBooleanField(SelectMultipleField):
    widget = widgets.ListWidget(prefix_label=False)
    option_widget = widgets.CheckboxInput()

Dieses Feld stecke ich in ein Formular:

Code: Alles auswählen

class EditTracker(TokenForm):
    enabled = BooleanField(u'Enabled?')
    valid_until = DateField(u'Valid Until', validators=[validators.required()])
    events = IterableBooleanField(u'Associate events to tracker', coerce=int)
Nun hole ich mir mein Objekt (Tracker) aus der Datenbank. Jeder Tracker kann mehrere Events zugeordnet haben. In meinem Editierformular für Tracker möchte ich jetzt alle Events angekreuzt bekommen, die dem Tracker zugeordnet sind. Das ganze basiert auf SQLAlchemy Klassen:

Code: Alles auswählen

class Tracker(database.Base):

    __tablename__ = 'tracker'
    
    ...
    events = relationship('Event', secondary=tracker_events, backref='tracker')
In meinem View rufe ich das Formular EditTracker wiefolgt auf:

Code: Alles auswählen

form = forms.EditTracker(request.form, tracker)
# alle events aus der Datenbank
form.events.choices = [(e.id, e.name)
                       for e in Event.query.order_by('event_name')]
...
return render_template('tracker/details.html', tracker=tracker, form=form)
Erstaunlicherweise ;) erkennt WTForms nicht, dass im tracker-objekt die Informationen zu den Checkboxen enthalten sind und kann diese natürlich nicht entsprechend ausfüllen. Man kann einem WTForm - Objekt ja auch noch Daten mittels **kwargs übergeben, was wohl in meinem Fall zielführend sein wird. Jetzt meine eigentliche Frage: Wie mache ich das am besten?

Denn der html-name aller Felder ist ja gleich (events in meinem Fall). Das übergeben der bestehenden Events im selben Format wie für die events.choices funktioniert auch nicht.

Die Dokumentation schreibt dazu:
**kwargs – If neither formdata or obj contains a value for a field, the form will assign the value of a matching keyword argument to the field, if provided.
Leider verstehe ich überhaupt nicht, wie WTForms das bei SelectMultipleFields anwendet. Die Durchsicht des Quellcodes gab mir leider auch keinen Hinweis. So gut sind meine Python-Kenntnisse leider noch nicht, dass ich daraus ersehen könnte, wie das genau gehandhabt wird.

Für zweckdienliche Hinweise oder bestehende Beispiele dafür wäre ich sehr dankbar:

Frank

PS:
hier noch das generierte HTML von WTForms

Code: Alles auswählen

<ul id="events">
<li><input type="checkbox" value="5" name="events" id="events-0"> <label for="events-0">another event</label></li>
<li><input type="checkbox" value="1" name="events" id="events-1"> <label for="events-1">Development</label></li>
<li><input type="checkbox" value="4" name="events" id="events-2"> <label for="events-2">foo bar baz</label></li>
<li><input type="checkbox" value="6" name="events" id="events-3"> <label for="events-3">noch eener</label></li>
</ul>
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Hier die Antwort auf meine Frage, damit der Thread wenigstens nicht sinnlos im Archiv versinkt:

Code: Alles auswählen

    selected = list()
    
    for event in tracker.events:
        selected.append(event.id)
    
    form = forms.EditTracker(formdata=request.form, events=selected)
Und hier noch mal das Formular:

Code: Alles auswählen

class EditTracker(TokenForm):
    enabled = BooleanField(u'Enabled?')
    valid_until = DateField(u'Valid Until', validators=[validators.required()])
    events = SelectMultipleField(u'Associate events to tracker')
Frank
Antworten