Pylons formencode con una variedad de elementos de formulario
-
13-09-2019 - |
Pregunta
Tengo una aplicación de Pylons y estoy usando Formencode y HTMLFill para manejar mis formularios. Tengo una variedad de campos de texto en mi plantilla (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>
Sin embargo, parece que no puedo descubrir cómo validar estos campos. Aquí está la entrada relevante de mi esquema
yardage = formencode.ForEach(formencode.validators.Int())
Estoy tratando de validar que cada uno de estos campos es un int. Sin embargo, no se produce validación para estos campos.
ACTUALIZARComo se solicita aquí, el código para la acción de este controlador. Sé que estaba funcionando ya que puedo validar otros campos de formulario.
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')
ACTUALIZARSe sugirió en IRC que cambio el nombre de los elementos de yardage[]
a yardage
Sin resultados. Todos deberían ser ints, pero poner f en uno de los elementos no hace que sea inválido. Como dije antes, puedo validar otros campos de formulario. A continuación se muestra todo mi esquema.
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())
Solución
Resulta que lo que quería hacer no estaba bien.
Modelo:
<tr>
<td>Yardage</td>
% for hole in range(9):
<td>${h.text('hole-%s.yardage'%(hole), maxlength=3, size=3)}</td>
% endfor
</tr>
(Debería haberlo hecho en un bucle para empezar). Notará que el nombre del primer elemento se convertirá en hole-1.yardage
. Entonces usaré Formencode.variedeCode
para convertir esto en un diccionario. Esto se hace en el
Esquema:
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())
El Holeschema validará que hole-#.par
y hole-#.yardage
son ambos ints y no están vacíos. formencode.ForEach
me permite aplicar HoleSchema
al diccionario que obtengo de pasar variable_decode=True
hacia @validate
decorador.
Aquí está el submit
acción de mi
Controlador:
@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!'
Utilizando el @validate
El decorador permite una forma mucho más limpia de validar y completar los formularios. los variable_decode=True
es muy importante o el diccionario no se creará correctamente.
Otros consejos
c.form_result = schema.to_python(request.params) - (without dict)
Parece funcionar bien.