Hi,

No, not another whinge - maybe there's life in @validate yet!

Locally to my project, I have a refactored @validate decorator sitting
in my lib/base.py, with most of the work of what was previously a 100+
line function extracted to methods on BaseController.  What's left of
the function lis shown at the end of this message - the extracted
methods are obvious enough if you have seen the original function.

The JSON twist:  The new _get_decoded() method adds the ability to
handle request bodies sent in JSON, and the new
_handle_validation_errors() method will render errors in JSON if
that's the format the client wants to accept.  Just a couple of lines
in each case.

In my controllers, "show" and "list" actions needed a small change to
render JSON if requested, but the create and update actions needed no
change at all.  Model objects all gained a to_dict() method, used by
the controllers to provide input to the json rendering.  In the
objects I most care about, the dict representation was tweaked a
little by hand.  Very modest effort for a basic JSON API I think.

This new @validate is clearly more extensible than the old one but I
still wonder about the extension interface.  For example, does the
request parsing bit (especially the JSON part) belong here, in (say)
an extensible or otherwise format-aware request object, or somewhere
else - a new validation or form object, say?

While we're here, I'm thinking of a Routes enhancement (in the form of
a personal extension if no-one else likes the idea) that allows a
{.format} syntax - already proposed to the URI Template people - as a
parameter style for optional format extensions.  The removal of large
numbers of "formatted routes" might even yield a small performance
benefit for some people, but even if it doesn't, I for one will be
pleased to help see some duplication disappear.  Meanwhile I have only
header-based conneg, which gets a bit tedious at times!

Finally, I would like a more sophisticated conneg function than my
current accepts_json(request), but before I start to write one, surely
such things exist already?

Regards,
Mike
m...@asplake.co.uk
http://positiveincline.com
http://twitter.com/asplake


def validate(schema=None, validators=None, form=None,
variable_decode=False,
             dict_char='.', list_char='-', post_only=True, state=None,
             on_get=False, **htmlfill_kwargs):
    """The Pylons @validate decorator refactored, with most of the
work done
    by controller methods defined on BaseController.  Enhanced to
accept JSON.
    """
    if state is None:
        state = PylonsFormEncodeState
    def wrapper(func, self, *args, **kwargs):
        """Decorator Wrapper function"""
        request = self._py_object.request

        # Skip the validation if on_get is False and its a GET
        if not on_get and request.environ['REQUEST_METHOD'] == 'GET':
            return func(self, *args, **kwargs)

        decoded = self._get_decoded(
                                variable_decode, dict_char, list_char,
                                post_only)
        self.form_result, self.form_errors = self._convert(
                                decoded, schema, validators, state,
                                variable_decode, dict_char, list_char)
        if self.form_errors:
            return self._handle_validation_errors(func, decoded,
                                                  self.form_errors,
form,
                                                  htmlfill_kwargs,
                                                  args, kwargs)
        else:
            return func(self, *args, **kwargs)
    return decorator(wrapper)

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to pylons-disc...@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-discuss+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en.

Reply via email to