2012-04-06 9 views
1

ich eine Form haben, um dynamisch zu geben scheint, die wie diese Art von aussieht:WTForms: Ich kann kein QuerySelectField einen Standardwert

class AddProductForm(Form): 
    title = TextField('Title') 
    type = QuerySelectField('Type', 
     query_factory=lambda: ProductType.query.order_by(ProductType.sequence).all()) 

    def __init__(self, formdata=None, obj=None, prefix='', **kwargs): 
     try: 
      product_type_id = ProductType.query.filter_by(name=obj['product_type']).one().product_type_id 
      kwargs.setdefault('type', product_type_id) 
     except NoResultFound: 
      pass 

     Form.__init__(self, formdata, obj, prefix, **kwargs) 

Wie Sie sehen, ich versuche, dies einzurichten ein zu geben vernünftiger Standardwert für den Produkttyp, wenn das Formular geladen wird. Während diese Art von Code für das Festlegen eines Titels als ein Beispiel funktionierte, funktioniert es jedoch nicht für den QuerySelectField-Typ. Hat jemand irgendwelche Ideen wie ich das beheben könnte?

Angenommen, dass dies nicht möglich ist, weiß jemand, wie ich Formularelemente dynamisch zu einem Formular hinzufügen kann?

+0

hi, hast du dieses Problem inzwischen gelöst? – Ib33X

Antwort

2

Verwendung Parameter wie:

QuerySelectField(allow_blank=True, blank_text=u'-- please choose --', ...) 

wählen Sie die Option Standard hinzufügen können

+0

Das war genau das, was ich brauchte – Anekdotin

6

Um einen Standardwert in einem QuerySelectField von WTForms zu definieren, können Sie es direkt in der Felddefinition tun:

my_field = QuerySelectField(
    label=u"My Label", 
    query_factory=lambda: Model.query(...), 
    get_pk=lambda item: item.id, 
    get_label=lambda item: item.name, 
    allow_blank=True, 
    default=lambda: Model.query.filter(...).one()) 

Allerdings ist es ein bisschen weniger einfach als das, was es aussieht. Berücksichtigen Sie dies:

  • Der Standardwert muss sein aufrufbar
  • Diese aufrufbar muss eine Objektinstanz des Modells zurückzukehren (nicht seine pk, sondern das gesamte Objekt)
  • Es wird nur sein wenn nicht verwendet obj oder Formulardaten verwendet wird, um die Formularinstanz initialisiert werden (in beiden Fällen wird der Standardwert ignoriert)

in Ihrem ca se, da Sie den Standardwert initialisiert wird ein Attribut Ihres obj, die Sie bei der Hand nicht bei der Initialisierung haben, können Sie eine Fabrik statt:

def add_product_form_factory(default_type_name): 
    class AddProductForm(Form): 
     title = TextField('Title') 
     type = QuerySelectField('Type', 
      query_factory=lambda: ProductType.query.order_by(ProductType.sequence).all(), 
      default=ProductType.query.filter_by(name=default_type_name).one() 
     ) 
    return AddProductForm 

Hier haben Sie eine Funktion, die die Form komponiert entsprechend die Parameter (in diesem Fall müssen Sie den Standard keine aufrufbar ist):

AddProductForm = add_product_form_factory(default_type_name='foo') 
form = AddProductForm() 

ps. Die Vorteile einer Formular-Factory bestehen darin, dass Sie dynamisch mit Formularen arbeiten, Felder erstellen oder zur Laufzeit eine Auswahl treffen können.

+0

Danke für den Hinweis: "Es wird nur verwendet, wenn keine Obj oder Formdata verwendet wird, um die Formularinstanz zu initialisieren (in beiden Fällen wird der Standardwert ignoriert)" – PartialOrder