decorators.py
2.91 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
# -*- coding: utf-8 -*-
from functools import wraps
from inspect import getargspec
from django.http import HttpResponse
from django.template.loader import render_to_string
from django.conf import settings
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.db import transaction
from common.util import json_decode, json_encode
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, template=None):
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 template:
res = {'html': render_to_string(template, res,
RequestContext(request))}
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
# żeby były linki do szablonów w PyCharm przy ajaxach
render_ajax = ajax
def render(template=None, mimetype=None):
mimetype = mimetype or settings.DEFAULT_CONTENT_TYPE
def decorator(func):
template_name = template or 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_name, output, RequestContext(request),
mimetype=mimetype)
return output
return renderer
return decorator