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 yardageSin 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())
¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top