2010-03-26 7 views
3

Python + Pylons의 오류를 처리하는 적절한 방법은 무엇입니까?Python + Pylons의 오류 처리

사용자가 컨트롤러를 통해 모델 클래스에 전달할 때 너무 짧아서 오류가 발생하는 양식을 통해 사용자가 암호를 설정한다고합시다. 오류 메시지가 전체 스크립트가 오류 페이지로 끝나는 것이 아니라 웹 페이지에 표시되도록 어떻게 처리해야합니까?

컨트롤러 자체에 오류 처리가 있어야합니까?

나는 분명히 자신을 설명하고 싶습니다.

감사합니다.

답변

2

양식 검증의 용도는 무엇입니까? formalchemy을 사용하고 있습니다. 내장 및 사용자 정의 유효성 검사기를 사용하여 입력 데이터의 유효성을 검사하고 찾은 오류가있는 목록을 제공합니다. 그런 다음 템플릿에 원하는 방식으로 목록을 표시 할 수 있습니다.

문서 here.

1

저는 formencode @validate 데코레이터를 사용합니다. 사용자 정의 유효성 검사기를 작성할 수도 있지만 유효성 검사 후 모델에서 발생하는 예외 처리 문제는 여전히 존재합니다.

모델 예외를 처리하고 c.form_errors를 채울 formencode와 비슷한 사용자 정의 액션 데코레이터를 작성할 수 있습니다.

+0

당신이이 작업을 수행하는 방법을 설명하기 위해 포함 할 수있는 샘플 코드가 우연히 당신은? 고맙습니다! – ensnare

+0

별도의 답변으로 코드 샘플을 추가했습니다. – Yaroslav

1

예제처럼 프로덕션 준비가 된 솔루션으로 위장하지 마십시오. 사실은 내가 pylons.decorators에서 데코레이터 대부분의 코드를 복사 한 :

from decorator import decorator 
from webob import UnicodeMultiDict 

class ModelException(Exception): 
    pass 

def handle_exceptions(form): 
    def wrapper(fn, self, *args,**kwargs): 
     try: 
      return fn(self, *args, **kwargs) 
     except ModelException, e: 
      errors = str(e) 
      params = request.POST 

      is_unicode_params = isinstance(params, UnicodeMultiDict) 
      params = params.mixed() 


      request.environ['pylons.routes_dict']['action'] = form 
      response = self._dispatch_call() 
      # XXX: Legacy WSGIResponse support 
      legacy_response = False 
      if hasattr(response, 'content'): 
       form_content = ''.join(response.content) 
       legacy_response = True 
      else: 
       form_content = response 
       response = self._py_object.response 

      # If the form_content is an exception response, return it 
      if hasattr(form_content, '_exception'): 
       return form_content 

      form_content = htmlfill.render(form_content, defaults=params, 
              errors=errors) 
      if legacy_response: 
       # Let the Controller merge the legacy response 
       response.content = form_content 
       return response 
      else: 
       return form_content 
    return decorator(wrapper) 


class HelloFormSchema(Schema): 
    allow_extra_fields = True 
    filter_extra_fields = True 
    name = formencode.validators.UnicodeString(not_empty=True) 
    email = formencode.validators.UnicodeString(not_empty=True) 

class HelloController(BaseController): 
    def new(self): 
     return render('/hello/new.html') 

    def view(self): 
     return 'created' 

    @handle_exceptions(form='new') 
    @validate(schema=HelloFormSchema(), form='new') 
    @restrict("POST") 
    def create(self): 
     #here is code interacting with model which potentially could raise exception: 
     if self.form_result['name'] == 'doe': 
      raise ModelException('user already exists!') 
     return redirect(url(controller='hello', action='view')) 

new.html :

${h.form(h.url(controller='hello', action='create'), 'post')} 
<dl> 
    <dt>Name</dt> 
    <dd>${h.text('name')}</dd> 
    <dt>Email</dt> 
    <dd>${h.text('email')}</dd> 
    <dd> 
    ${h.submit('create', 'Create')} 
    </dd> 
</dl> 
${h.end_form()}