Pergunta

Eu tenho um aplicativo Pylons e estou usando o FormEncode e o HTMLFill para lidar com meus formulários. Eu tenho uma variedade de campos de texto no meu modelo (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>

No entanto, não consigo descobrir como validar esses campos. Aqui está a entrada relevante do meu esquema

yardage = formencode.ForEach(formencode.validators.Int())

Estou tentando validar que cada um desses campos é uma int. No entanto, nenhuma validação ocorre para esses campos.

ATUALIZARConforme solicitado aqui é o código para a ação deste controlador. Eu sei que estava funcionando, pois posso validar outros campos de forma.

    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')

ATUALIZARFoi sugerido no IRC que eu mudei o nome dos elementos de yardage[] para yardageNenhum resultado. Todos devem ser ints, mas colocar F em um dos elementos não faz com que seja inválido. Como eu disse antes, sou capaz de validar outros campos de forma. Abaixo está todo o meu 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())
Foi útil?

Solução

Acontece que o que eu queria fazer não estava certo.

Modelo:

<tr>
  <td>Yardage</td>
  % for hole in range(9):
  <td>${h.text('hole-%s.yardage'%(hole), maxlength=3, size=3)}</td>
  % endfor
</tr>

(Deveria ter feito isso em um loop para começar.) Você notará que o nome do primeiro elemento se tornará hole-1.yardage. Vou então usar FormEncode.variabledecode para transformar isso em um dicionário. Isso é feito no

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())

O Holeschema vai validar que hole-#.par e hole-#.yardage são INTs e não estão vazios. formencode.ForEach Permite -me aplicar HoleSchema para o dicionário que recebo de passar variable_decode=True para o @validate decorador.

Aqui está o submit ação do meu

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!'

Usando o @validate O decorador permite uma maneira muito mais limpa de validar e preencher os formulários. o variable_decode=True é muito importante ou o dicionário não será criado corretamente.

Outras dicas

c.form_result = schema.to_python(request.params) - (without dict)

Parece funcionar bem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top