def apply_ args kwargs Decorator for per-view rules applying Usage app

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
def apply_(*args, **kwargs):
"""
Decorator for per-view rules applying
Usage:
@apply_('rule1', 'rule2', 'rule3', default_context={'key': 'foo'})
def some_view(request, arg1, arg2):
pass
"""
rules = []
for arg in args:
if isinstance(arg, (list, tuple)):
rules += list(arg)
elif isinstance(arg, str):
rules += [arg]
else:
raise ValueError("Wrong arg %s for apply_" % (arg,))
default_context = None
if kwargs:
if kwargs.keys() != ['default_context']:
raise ValueError('Only default_context is allowed keyword argument')
else:
default_context = kwargs['default_context']
def checker(view_func):
def wrapper(*args, **kwargs):
if default_context is not None:
extra = default_context
else:
extra = {}
extra['caller'] = view_func.__name__
keys = getargspec(view_func).args
for i, key in enumerate(keys):
try:
extra[key] = args[i]
except IndexError:
extra[key] = kwargs[key]
if 'city' not in extra:
raise ValueError('Each rule requires city in args')
city = extra['city']
for rule_name in rules:
rule = RULES[rule_name]
ok, reason = rule(city, extra)
if not ok:
return HttpResponse(unicode(reason),
mimetype='text/plain',
status=404)
return view_func(*args, **kwargs)
view_func._applied_rules = rules
return wraps(view_func)(wrapper)
return checker