문제

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인지 확인하려고합니다. 그러나 이러한 필드에 대한 검증은 발생하지 않습니다.

업데이트여기에 요청 된 대로이 컨트롤러의 조치 코드가 있습니다. 다른 형태의 필드를 검증 할 수 있으므로 작동하고 있다는 것을 알고 있습니다.

    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)

잘 작동하는 것 같습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top