Piloni FormEncode con una serie di elementi del modulo
-
13-09-2019 - |
Domanda
Ho un app Piloni e sto usando FormEncode e HtmlFill per gestire le mie forme. Ho una serie di campi di testo nel mio modello (Mako)
<tr> <td>Yardage</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> </tr>
Comunque, io non riesco a capire come convalidare questi campi. Ecco la voce corrispondente dal mio Schema
yardage = formencode.ForEach(formencode.validators.Int())
Sto cercando di convalidare che ognuno di questi campi è un Int. Tuttavia, nessuna convalida si verifica per questi campi.
Aggiorna Come richiesto ecco il codice per l'azione di questo controller. So che lavorava come posso convalidare altri campi del modulo.
def submit(self): schema = CourseForm() try: c.form_result = schema.to_python(dict(request.params)) except formencode.Invalid, error: c.form_result = error.value c.form_errors = error.error_dict or {} c.heading = 'Add a course' html = render('/derived/course/add.html') return htmlfill.render( html, defaults = c.form_result, errors = c.form_errors ) else: h.redirect_to(controler='course', action='view')
Aggiorna
E 'stato suggerito su IRC che a cambiare il nome degli elementi da yardage[]
a yardage
Nessun risultato. Dovrebbero essere tutti interi, ma mettendo in f in uno degli elementi non causare che sia valido. Come ho detto prima, sono in grado di convalidare gli altri campi del modulo. Qui di seguito è il mio intero schema.
import formencode class CourseForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True name = formencode.validators.NotEmpty(messages={'empty': 'Name must not be empty'}) par = formencode.ForEach(formencode.validators.Int()) yardage = formencode.ForEach(formencode.validators.Int())
Soluzione
Si scopre che quello che volevo fare non era giusto.
modello :
<tr>
<td>Yardage</td>
% for hole in range(9):
<td>${h.text('hole-%s.yardage'%(hole), maxlength=3, size=3)}</td>
% endfor
</tr>
(dovrebbe essere fatto in un ciclo per cominciare.) Si noterà che il nome del primo elemento diventerà hole-1.yardage
. Io poi usare FormEncode.variabledecode
di trasformare questo in un dizionario. Questo viene fatto nel
Schema :
import formencode
class HoleSchema(formencode.Schema):
allow_extra_fields = False
yardage = formencode.validators.Int(not_empty=True)
par = formencode.validators.Int(not_empty=True)
class CourseForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
name = formencode.validators.NotEmpty(messages={'empty': 'Name must not be empty'})
hole = formencode.ForEach(HoleSchema())
Il HoleSchema sarà convalidare che hole-#.par
e hole-#.yardage
sono entrambi interi e non sono vuote. formencode.ForEach
mi permette di applicare HoleSchema
al dizionario che ricevo dal passaggio variable_decode=True
al decoratore @validate
.
Ecco l'azione submit
dal mio
Regolatore :
@validate(schema=CourseForm(), form='add', post_only=False, on_get=True,
auto_error_formatter=custom_formatter,
variable_decode=True)
def submit(self):
# Do whatever here.
return 'Submitted!'
Utilizzando il decoratore @validate
permette un modo molto più pulito di convalidare e compilare i moduli. Il variable_decode=True
è molto importante o il dizionario non verrà creato correttamente.
Altri suggerimenti
c.form_result = schema.to_python(request.params) - (without dict)
Sembra che funziona bene.