This repository has been archived by the owner on Dec 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
mixins.py
142 lines (111 loc) · 4.39 KB
/
mixins.py
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
from __future__ import unicode_literals
from django.conf import settings
from django.http import Http404, JsonResponse
from django.template.loader import render_to_string
class AjaxResponseAction():
""" Represents list of actions available after ajax response """
NOTHING = "nothing"
REDIRECT = "redirect"
REFRESH = "refresh"
choices = (
NOTHING,
REDIRECT,
REFRESH
)
class AjaxResponseStatus():
""" Represents list of status available at ajax response """
ERROR = "error"
SUCCESS = "success"
choices = (
ERROR,
SUCCESS,
)
class AjaxResponseMixin(object):
""" Mixin responsible to give the JSON response """
action = AjaxResponseAction.NOTHING
json_status = AjaxResponseStatus.SUCCESS
def json_to_response(self, action=None, json_status=None, success_url=None,
json_data=None, **response_kwargs):
""" Valid response with next action to be followed by the JS """
data = {
"status": self.get_status(json_status),
"action": self.get_action(action),
"extra_data": self.get_json_data(json_data or {})
}
if self.action == AjaxResponseAction.REDIRECT:
data["action_url"] = success_url or self.get_success_url()
return JsonResponse(data, **response_kwargs)
def get_action(self, action=None):
""" Returns action to take after call """
if action:
self.action = action
if self.action not in AjaxResponseAction.choices:
raise ValueError(
"Invalid action selected: '{}'".format(self.action))
return self.action
def get_status(self, json_status=None):
""" Returns status of for json """
if json_status:
self.json_status = json_status
if self.json_status not in AjaxResponseStatus.choices:
raise ValueError(
"Invalid status selected: '{}'".format(self.json_status))
return self.json_status
def get_json_data(self, json_data=None):
""" Returns any extra data to add to json """
return json_data or {}
class FormAjaxMixin(AjaxResponseMixin):
""" Mixin responsible to take care of form ajax submission """
def form_invalid(self, form, prefix=None):
""" If form invalid return error list in JSON response """
response = super(FormAjaxMixin, self).form_invalid(form)
if self.request.is_ajax():
data = {
"errors_list": self.add_prefix(form.errors, prefix),
}
return self.json_to_response(status=400, json_data=data,
json_status=AjaxResponseStatus.ERROR)
return response
def get_success_url(self):
""" """
if not self.request.is_ajax():
return super(FormAjaxMixin, self).get_success_url()
return None
def form_valid(self, form):
""" If form valid return response with action """
response = super(FormAjaxMixin, self).form_valid(form)
if self.request.is_ajax():
return self.json_to_response()
return response
def add_prefix(self, errors, prefix):
"""Add form prefix to errors"""
if not prefix:
prefix = self.get_prefix()
if prefix:
return {"%s-%s" % (prefix, k): v for k, v in errors.items()}
return errors
class PartialAjaxMixin(object):
""" Mixin responsible to return the JSON with template rendered """
partial_title = None
def get_partial_title(self):
return self.partial_title
def get_context_data(self, **kwargs):
context = super(PartialAjaxMixin, self).get_context_data(**kwargs)
partial_title = self.get_partial_title()
if partial_title:
context.update({
'title': partial_title
})
return context
def render_to_response(self, context, **response_kwargs):
""" Returns the rendered template in JSON format """
if self.request.is_ajax():
data = {
"content": render_to_string(
self.get_template_names(), context, request=self.request)
}
return JsonResponse(data)
if settings.DEBUG:
return super(PartialAjaxMixin, self).render_to_response(
context, **response_kwargs)
raise Http404()