Пилоны, FormEncode и внешняя проверка - PullRequest
1 голос
/ 04 августа 2010

Я создаю веб-интерфейс для серверного приложения, используя Pylons 1.0.
Прямо сейчас я пишу первую форму и столкнулся с проблемой, связанной с проверкой. Использование FormEncode и @валидация декоратора. Я могу легко проверить пользовательский ввод с точки зрения клиента, но когда я отправляю данные на сервер, он может выполнять дополнительные проверки и в конечном итоге отбрасывать исключения, которые мне нужно показать пользователю.* Мой вопрос: существует ли краткий способ интеграции / эмуляции обработки этого исключения в поток FormEncode / validate?Например, заново отобразить форму с заполненными полями и сообщением об ошибке, как это произошло бы, если бы исключение произошло от самого @validate?* Таким образом, в случае исключения на стороне сервера я вижу сообщение «flash», но форма, конечно, будет иметь пустые поля: /

Ответы [ 2 ]

1 голос
/ 05 августа 2010

Мне нравится реализовывать:

from formencode import htmlfill

def create(self):
    if request.params:
        try:
            Post.validate(request.paramse)
            post = helpers.load_attributes(Post(), request.params)
            model.save_to_server(post)

            flash('OK', 'success')
            redirect(...)
        except InvalidException as e:
            for key, message in e.unpack_errors().iteritems():
                flash(message, 'error')

    return htmlfill.render(render('/blogs/create.html'), request.params)

где мой Post.validate:

@staticmethod
def validate(data):
    schema = PostSchema()
    schema.to_python(data)

Таким образом, если впервые (request.params пусто) html заполняет форму ничем, когда пользователь отправляет данные html заполняет форму request.params

0 голосов
/ 06 августа 2010

Другой способ (вдохновленный этим ответом ) - написать декоратор, похожий на @validate, который будет перехватывать нужные исключения и использовать htmlfill для отображения их сообщения:

def handle_exceptions(form):

    def wrapper(func, self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except MyBaseException, e:
            request = self._py_object.request
            errors = { "exception" : unicode(e) }

            params = request.POST
            decoded = params.mixed()
            request.environ['REQUEST_METHOD'] = 'GET'
            self._py_object.tmpl_context.form_errors = errors
            request.environ['pylons.routes_dict']['action'] = form
            response = self._dispatch_call()

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

            htmlfill_kwargs2 = {}
            htmlfill_kwargs2.setdefault('encoding', request.charset)
            return htmlfill.render(response, defaults=params, errors=errors,
                                   **htmlfill_kwargs2)
    return decorator(wrapper)

Декоратор будет использоваться как:

@handle_exceptions("edit")
@validate(schema=form.UserForm(), form="edit")
def add_user(self):
    if request.POST:
        u = helpers.load_attributes(User(), self.form_result)
        model.save_to_server(u)
...