Пилоны FormEncode с массивом элементов формы - PullRequest
2 голосов
/ 15 июня 2009

У меня есть приложение Pylons, и я использую FormEncode и HtmlFill для обработки моих форм. У меня есть массив текстовых полей в моем шаблоне (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>

Однако я не могу понять, как проверить эти поля. Вот соответствующая запись из моей схемы

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

Я пытаюсь проверить, что каждое из этих полей является Int. Однако для этих полей проверка не выполняется.

UPDATE В соответствии с запросом здесь приведен код действия этого контроллера. Я знаю, что это работает, так как я могу проверить другие поля формы.

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

UPDATE На IRC было предложено изменить название элементов с yardage[] на yardage Безрезультатно. Все они должны быть целыми числами, но вставка f в один из элементов не делает его недействительным. Как я уже говорил, я могу проверить другие поля формы. Ниже вся моя схема.

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

Ответы [ 2 ]

5 голосов
/ 17 июня 2009

Оказывается, то, что я хотел сделать, было не совсем правильно.

Template

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

(Для начала нужно было сделать это в цикле.) Вы заметите, что имя первого элемента станет hole-1.yardage. Затем я буду использовать <a href="http://www.formencode.org/en/latest/modules/variabledecode.html" rel="nofollow noreferrer">FormEncode.variabledecode</a>, чтобы превратить это в словарь. Это сделано в

Схема

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

HoleSchema подтвердит, что hole-#.par и hole-#.yardage являются целыми числами и не пусты. formencode.ForEach позволяет мне применить HoleSchema к словарю, который я получаю при передаче variable_decode=True в @validate декоратор.

Вот действие submit от моего

Контроллер

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

Использование декоратора @validate позволяет гораздо более простой способ проверки и заполнения форм. variable_decode=True очень важно, иначе словарь не будет создан должным образом.

1 голос
/ 26 октября 2010
c.form_result = schema.to_python(request.params) - (without dict)

Кажется, работает нормально.

...