d6f70501d7e117e943e5f13ee0d079dbee03e738
[wolnelektury.git] / apps / ajaxable / utils.py
1 from django.http import HttpResponse, HttpResponseRedirect
2 from django.shortcuts import render_to_response
3 from django.template import RequestContext
4 from django.utils.encoding import force_unicode
5 from django.utils.functional import Promise
6 from django.utils.http import urlquote_plus
7 from django.utils import simplejson
8 from django.utils.translation import ugettext_lazy as _
9
10
11 class LazyEncoder(simplejson.JSONEncoder):
12     def default(self, obj):
13         if isinstance(obj, Promise):
14             return force_unicode(obj)
15         return obj
16
17 # shortcut for JSON reponses
18 class JSONResponse(HttpResponse):
19     def __init__(self, data={}, callback=None, **kwargs):
20         # get rid of mimetype
21         kwargs.pop('mimetype', None)
22         data = simplejson.dumps(data)
23         if callback:
24             data = callback + "(" + data + ");" 
25         super(JSONResponse, self).__init__(data, mimetype="application/json", **kwargs)
26
27
28
29 class AjaxableFormView(object):
30     """Subclass this to create an ajaxable view for any form.
31
32     In the subclass, provide at least form_class.
33
34     """
35     form_class = None
36     # override to customize form look
37     template = "ajaxable/form.html"
38     submit = _('Send')
39     
40     title = ''
41     success_message = ''
42     formname = "form"
43     full_template = "ajaxable/form_on_page.html"
44
45     def __call__(self, request):
46         """A view displaying a form, or JSON if `ajax' GET param is set."""
47         ajax = request.GET.get('ajax', False)
48         if request.method == "POST":
49             form = self.form_class(data=request.POST)
50             if form.is_valid():
51                 self.success(form, request)
52                 redirect = request.GET.get('next')
53                 if not ajax and redirect:
54                     return HttpResponseRedirect(urlquote_plus(
55                             redirect, safe='/?=&'))
56                 response_data = {'success': True, 
57                     'message': self.success_message, 'redirect': redirect}
58             else:
59                 response_data = {'success': False, 'errors': form.errors}
60             if ajax:
61                 return HttpResponse(LazyEncoder(ensure_ascii=False).encode(response_data))
62         else:
63             form = self.form_class()
64             response_data = None
65
66         template = self.template if ajax else self.full_template
67         return render_to_response(template, {
68                 self.formname: form, 
69                 "title": self.title,
70                 "submit": self.submit,
71                 "response_data": response_data,
72                 "ajax_template": self.template,
73             },
74             context_instance=RequestContext(request))
75
76     def success(self, form, request):
77         """What to do when the form is valid.
78         
79         By default, just save the form.
80
81         """
82         return form.save(request)