Added support for mapping parameters in the URI to parameters for a

controller, including validation support.
This commit is contained in:
Jonathan LaCour
2010-10-22 09:57:27 -04:00
parent 0197aebd77
commit ced0eda4ba
2 changed files with 58 additions and 4 deletions

View File

@@ -71,7 +71,7 @@ class Pecan(object):
def route(self, node, path):
path = path.split('/')[1:]
node, remainder = lookup_controller(node, path)
return node
return node, remainder
def handle_security(self, controller):
if controller.pecan.get('secured', False):
@@ -90,11 +90,20 @@ class Pecan(object):
for hook in state.hooks:
getattr(hook, hook_type)(*args)
def get_params(self, all_params, argspec):
def get_params(self, all_params, remainder, argspec):
valid_params = dict()
# handle params that are POST or GET variables first
for param_name, param_value in all_params.iteritems():
if param_name in argspec.args:
valid_params[param_name] = param_value
# handle positional arguments
for i, value in enumerate(remainder):
if len(argspec.args) > (i+1):
if valid_params.get(argspec.args[i+1]) is None:
valid_params[argspec.args[i+1]] = value
return valid_params
def validate(self, schema, params=None, json=False):
@@ -111,7 +120,7 @@ class Pecan(object):
if '.' in path.split('/')[-1]:
path, format = path.split('.')
content_type = self.get_content_type(format)
controller = self.route(self.root, path)
controller, remainder = self.route(self.root, path)
# determine content type
if content_type is None:
@@ -129,6 +138,7 @@ class Pecan(object):
# fetch and validate any parameters
params = self.get_params(
dict(state.request.str_params),
remainder,
controller.pecan['argspec']
)
if 'schema' in controller.pecan:

View File

@@ -1,5 +1,7 @@
from pecan import Pecan, expose, request, response, redirect
from webtest import TestApp
from formencode import Schema, validators
class TestBase(object):
@@ -192,4 +194,46 @@ class TestEngines(object):
assert r.status_int == 302
r = r.follow()
assert r.status_int == 200
assert r.body == 'it worked!'
assert r.body == 'it worked!'
def test_uri_to_parameter_mapping(self):
class RootController(object):
@expose()
def test(self, one, two):
assert one == '1'
assert two == '2'
return 'it worked'
app = TestApp(Pecan(RootController()))
r = app.get('/test/1/2')
assert r.status_int == 200
assert r.body == 'it worked'
def test_uri_to_parameter_mapping_with_validation(self):
class TestSchema(Schema):
one = validators.Int(not_empty=True)
two = validators.Int(not_empty=True)
class RootController(object):
@expose(schema=TestSchema())
def test(self, one, two):
assert request.validation_error is None
assert one == 1
assert two == 2
return 'it worked'
@expose(schema=TestSchema())
def fail(self, one, two):
assert request.validation_error is not None
assert one == 'one'
assert two == 'two'
return 'it failed'
app = TestApp(Pecan(RootController()))
r = app.get('/test/1/2')
assert r.status_int == 200
assert r.body == 'it worked'
r = app.get('/fail/one/two')
assert r.status_int == 200
assert r.body == 'it failed'