Пилоны Formencode с множеством элементов формы
-
13-09-2019 - |
Вопрос
У меня есть приложение Pylons, и я использую Formencode и Htmlfill для обработки моих форм. У меня есть множество текстовых полей в моем шаблоне (Мако)
<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. Тем не менее, для этих полей не происходит проверки.
ОБНОВИТЬКак запрошено здесь код для действия этого контроллера. Я знаю, что это работало, так как я могу проверить другие поля формы.
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')
ОБНОВИТЬНа IRC было предложено, чтобы я менял название элементов с yardage[]
к yardage
Безрезультатно. Все они должны быть INT, но внедрение 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())
Решение
Оказывается, то, что я хотел сделать, было не совсем правильно.
Шаблон:
<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
. Анкет Затем я буду использовать Formencode.variabledecode
Чтобы превратить это в словарь. Это делается в
Схема:
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
оба INT и не пусты. 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
очень важно, или словарь не будет должным образом создан.
Другие советы
c.form_result = schema.to_python(request.params) - (without dict)
Кажется, работает нормально.