Or, an example about introspection targeting Python's functions.
I really like the way CherryPy maps GET parameters to the parameters of the handling function (usually, methods). I miss this mapping in Django, therefore I implemented it. I am "lazy" and I did not search Django's API for something related to this — I did this for pleasure.
Anyway, I have implemented a decorator, params_from_GET that adds this functionality to Django-handlers. You have to read the docstring to read the usage.
Code dump (licensed under public domain):
import inspect
def get_func_args(func):
"""
Returns a generators of pairs (parameter name, default value)
of the target function.
"""
(args, varargs, varkw, defaults) = inspect.getargspec(func)
if defaults is None:
defaults = ()
offset = len(args) - len(defaults)
return args[:offset], dict(zip(args[offset:], defaults))
def params_from(func, method, default_value=''):
"""
Returns a decorator, see params_from_GET.
"""
# get the default params
args, params = get_func_args(func)
if args[0] != "request":
raise TypeError("First parameters needs to be 'request'")
for param in args[1:]:
params[param] = default_value=''
def wrapper(request, **orig_kwargs):
# copy the parameters
kwargs = params.copy()
# get the map for the defined method, e.g GET
method_dict = getattr(request, method)
# set the request object
kwargs['request'] = request
for key in params:
# fill with values that were sent by the user
if key in method_dict:
kwargs[key] = method_dict[key]
kwargs.update(orig_kwargs)
return func(**kwargs)
return wrapper
def params_from_GET(func):
"""
The decorator pics up a handler function and fetches the
values from the GET map.
For example:
@params_from_GET
handler(request, foo, bar):
pass
Is the same as:
handler(request):
foo = request.GET('foo', '')
bar = request.GET('bar', '')
"""
return params_from(func, 'GET')
Update: added support for the keyword arguments that may be passed to the dispatcher by urls.py.
0 comments:
Post a Comment