from django.http import HttpResponseBadRequest from functools import wraps from inspect import getargspec from django.http import HttpResponse from simplejson import loads as json_decode, dumps as json_encode from common.util import stringify_keys from django.db import transaction #https://djangosnippets.org/snippets/771/ def ajax_required(f): def wrap(request, *args, **kwargs): if not request.is_ajax(): return HttpResponseBadRequest() return f(request, *args, **kwargs) wrap.__doc__=f.__doc__ wrap.__name__=f.__name__ return wrap class AjaxError(Exception): pass def json_decode_fallback(value): try: return json_decode(value) except ValueError: return value def ajax(login_required=False, method=None, encode_result=True): def decorator(fun): @wraps(fun) def ajax_view(request, *args, **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.items() 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, *args, **kwargs) except AjaxError as e: res = {'result': e.args[0]} transaction.rollback() if encode_result: if 'result' not in res: res['result'] = 'ok' return HttpResponse(json_encode(res)) else: return res return ajax_view return decorator