2014-06-19 14 views
6

Ho questo modulo d'ordine che consente ai miei utenti di creare un ordine. Un ordine è costituito da più tuple di (producetype, quantity). Producetype dovrebbe essere reso in un modulo <select> mentre la quantità può essere solo un input. Le scelte del tipo di prodotto dovrebbero essere aggiunte dinamicamente perché potrebbero cambiare. Attualmente, ho scritto questo in html nudoWTForm: FieldList con SelectField, come si esegue il rendering?

enter image description here

Vorrei utilizzare WTForm per questo, perché WTForm davvero semplifica il mio codice. Tuttavia, sono in grado di farlo:

Codice:

class OrderEntryForm(Form): 
    quantity = IntegerField('Quantity', 
          [validators.Required(), validators.NumberRange(min=1)]) 
    # we will be dynamically adding choices 
    producetype = SelectField('Produce', 
          [validators.Required()], 
          choices=[]) 

class OrderForm(Form): 
    name = TextField('Crop', [validators.Length(min=3, max=60)]) 
    due_date = DateField('Due Date', [validators.required()]) 
    order_entries = FieldList(FormField(OrderEntryForm)) 

Ho le seguenti domande:

  1. Come posso aggiungere dinamicamente le scelte al order_entries campo della OrderForm?
  2. Se si dispone di un ordine, order = { name:hello, due_date:2014-06-18, order_entries:[ {producetype_id: 1, quantity: 2}, {producetype_id: 3, quantity: 4}] }, come è possibile popolare il mio OrderEntryForm valori con OrderEntryForm?

Il mio codice è disponibile qui: https://gist.github.com/vicngtor/f8c8f0519dbd6b3b6110

risposta

-1

Aggiungi un SubmitField alla vostra per OrderForm:

submit_something = SubmitField((u'Add something')) 

e poi lo chiamano dalla visualizzazione, e utilizzare il metodo append_entry di FieldList:

if form.submit_something.data: 
     form.order_entries.append_entry() 
     return render_template('yourtemplate.html', form=form) 

Spero che questo aiuti!

+0

non ho alcun problema la presentazione. Ho problemi nel prepopolare il modulo (si prega di leggere attentamente la domanda) – disappearedng

4

Come posso aggiungere dinamicamente le scelte al campo order_entries del OrderForm

Questo dipende da cosa si intende

Se vuoi dire che si desidera aggiungere elementi linee per il modulo dopo il rendering. Devi usare la manipolazione DOM per aggiungerli dal lato client. WTForms ha una convenzione di denominazione per l'indirizzamento degli indici nei campi modulo. È solo name="<form-field)name>-<index>". Se aggiungi un nome utilizzando javascript che segue questa convenzione, WTForms saprà come gestirlo sul back-end.

Se si intende avere un elenco di scelta dinamico, è possibile eseguire semplicemente l'iterazione dello FieldList nel modulo dopo l'istanza. Puoi assegnare choices a qualsiasi iterable di 2-tuple. Nell'esempio che segue li sto assegnando direttamente ma potrebbero essere facilmente recuperati dallo storage.

order_form = OrderForm() 
for sub_form in order_form.order_entries: 
    sub_form.producetype.choices = [('2', 'apples'), ('2', 'oranges')] 

come si può riempire la mia OrderForm con i valori OrderEntryForm giuste?

È possibile associare direttamente gli oggetti al modulo utilizzando l'argomento chiave obj.WTForms è abbastanza intelligente per generare dinamicamente il modulo dagli attributi dell'oggetto.

from wtforms import Form, IntegerField, SelectField, TextField, FieldList, FormField 
from wtforms import validators 
from collections import namedtuple 

OrderEntry = namedtuple('OrderEntry', ['quantity', 'producetype']) 
Order = namedtuple('Order', ['name', 'order_entries']) 

class OrderEntryForm(Form): 
    quantity = IntegerField('Quantity', 
          [validators.Required(), validators.NumberRange(min=1)]) 
    # we will be dynamically adding choices 
    producetype = SelectField('Produce', 
          [validators.Required()], 
          choices=[ 
           (1, 'carrots'), 
           (2, 'turnips'), 
          ]) 

class OrderForm(Form): 
    name = TextField('Crop', [validators.Length(min=3, max=60)]) 
    order_entries = FieldList(FormField(OrderEntryForm)) 

# Test Print of just the OrderEntryForm 
o_form = OrderEntryForm() 
print o_form.producetype() 

# Create a test order 
order_entry_1 = OrderEntry(4, 1) 
order_entry_2 = OrderEntry(2, 2) 

order = Order('My First Order', [order_entry_1, order_entry_2]) 

order_form = OrderForm(obj=order) 

print order_form.name 
print order_form.order_entries 

L'esempio sopra crea un campione Order e di trasferirlo la parola chiave obj. Su rendono questo genererà il seguente (senza stile):

enter image description here

+0

Questo è stato molto utile. Grazie. Tuttavia, ho un altro problema direttamente correlato alla tua soluzione. Saresti così gentile da dare un'occhiata anche a te? http://stackoverflow.com/questions/24324161/wtform-how-do-i-tell-form-to-use-a-custom-method-for-one-particular-attribute – disappearedng

Problemi correlati