Pylons,FormEncode和外部验证

时间:2010-08-04 16:16:25

标签: validation pylons

我正在使用Pylons 1.0构建服务器端应用程序的Web前端 现在我正在编写第一个表单,我正面临着有关验证的问题。使用FormEncode和@validate装饰器,我可以从客户端角度轻松验证用户输入,但是当我将数据提交给服务器,它可能会执行额外的检查,并最终丢弃我需要向用户显示的异常。

我的问题:是否有简洁的方法将此异常处理集成/模拟到FormEncode / validate流程中?例如,重新显示带有填充字段的表单和错误消息,如果异常来自@validate本身会发生错误消息吗?

这就是我现在所拥有的:

def edit(self, id):
    return render('/edit_user.mako')

@validate(schema=form.UserForm(), form="edit")
def add_user(self):
    if request.POST:
        u = helpers.load_attributes(User(), self.form_result)
        try:
            model.save_to_server(u)
        except MyBaseException, exc:
            helpers.flash(unicode(exc))
            return self.edit()

这样,在服务器端异常的情况下,我可以看到“flash”消息,但当然形式将有空字段:/

2 个答案:

答案 0 :(得分:1)

我喜欢实施:

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填充表单

答案 1 :(得分:0)

另一种方式(受this answer启发)是编写类似于@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)