开发者

Pylons, FormEncode and external validation

开发者 https://www.devze.com 2023-01-10 10:05 出处:网络
I\'m building a web frontend to a server-side application, using Pylons 1.0. Right now I\'m writing the first form, and I\'m facing a problem concerning validation.. Using FormEncode and the @validate

I'm building a web frontend to a server-side application, using Pylons 1.0.

Right now I'm writing the first form, and I'm facing a problem concerning validation.. Using FormEncode and the @validate decorator I can easily validate the user input from a client-side perspective, but when I submit the data to the server, it may perform additional checks and eventually throw back exceptions that I need to show to the user.

My question: is there a concise way to integrate/emulate this exception handling into the FormEncode/validate flow? For example, redisplay the form with filled fields and an error message, as would happen if the exception had come from the @validate itself?

Here's what I have at the moment:

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()

In this way, in case of a server-side exception I can see the "flash" message b开发者_运维问答ut the form of course will have empty fields :/


I like to implement:

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)

where my Post.validate:

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

In this way, if is the first time (request.params empty) html fills form with nothing, when user send datas html fills form with request.params


Another way (inspired by this answer) is to write a decorator similar to @validate that would catch the desired exceptions and use htmlfill to display their message:

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)

The decorator would be used like:

@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)
0

精彩评论

暂无评论...
验证码 换一张
取 消