decorators.py
3.59 KB
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# -*- coding: utf-8 -*-
from functools import wraps
from inspect import getargspec
from django.http import HttpResponse
from django.utils.simplejson import loads as json_decode, dumps as json_encode
from django.utils.functional import curry
from django.conf import settings
from django.shortcuts import render_to_response
from django.template import RequestContext, generic_tag_compiler, Node
from django.template import TemplateSyntaxError, Variable
from django.db import transaction
from common.util import stringify_keys
class AjaxError(Exception):
pass
def json_decode_fallback(value):
try:
return json_decode(value)
except ValueError:
return value
def ajax(login_required=True, method=None, encode_result=True):
def decorator(fun):
@wraps(fun)
def ajax_view(request):
kwargs = {}
request_params = None
if method == 'post':
request_params = request.POST
elif method == 'get':
request_params = request.GET
fun_params, xx, fun_kwargs, xxxx = getargspec(fun)
if request_params:
request_params = dict((key, json_decode_fallback(value))
for key, value in request_params.iteritems()
if fun_kwargs or key in fun_params)
kwargs.update(stringify_keys(request_params))
res = None
if login_required and not request.user.is_authenticated():
res = {'result': 'logout'}
if not res:
try:
res = fun(request, **kwargs)
except AjaxError as e:
transaction.rollback()
res = {'result': e.args[0]}
if encode_result:
if 'result' not in res:
res['result'] = 'ok'
return HttpResponse(json_encode(res), mimetype='application/json')
else:
return res
return ajax_view
return decorator
def render(template=None, mimetype=None):
mimetype = mimetype or settings.DEFAULT_CONTENT_TYPE
template1 = template
def decorator(func):
template = template1 # no cóż...
if not template:
template = func.__name__ + '.html'
@wraps(func)
def renderer(request, *args, **kw):
output = func(request, *args, **kw)
if isinstance(output, (list, tuple)):
return render_to_response(output[1], output[0],
RequestContext(request), mimetype=mimetype)
elif isinstance(output, dict):
return render_to_response(template, output,
RequestContext(request), mimetype=mimetype)
return output
return renderer
return decorator
def simple_tag(register, takes_context=False):
def decorator(func):
params, xx, xxx, defaults = getargspec(func)
if takes_context:
if params[0] == 'context':
params = params[1:]
else:
raise TemplateSyntaxError("Any tag function decorated with takes_context=True must have a first argument of 'context'")
class SimpleNode(Node):
def __init__(self, vars_to_resolve):
self.vars_to_resolve = map(Variable, vars_to_resolve)
def render(self, context):
resolved_vars = [var.resolve(context) for var in self.vars_to_resolve]
if takes_context:
args = [context] + resolved_vars
else:
args = resolved_vars
try:
return func(*args)
except Exception as e:
raise
return type(e).__name__+': '+str(e)
compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode)
compile_func.__doc__ = func.__doc__
register.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
return func
return decorator