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 | from django.template.loader import get_template
from django.template import RequestContext
from django import http
class BaseView(object):
"""
BaseView provides a class that is instantiated and then
called like a function.
__init__ called without arguments.
You must just override the __call__ method.
"""
def __new__(cls, *args, **kwargs):
obj = super(BaseView, cls).__new__(cls)
return obj(*args, **kwargs)
def __call__(self, *args, **kwargs):
pass
class View(BaseView):
"""
View provides a basic django view _class_
It is instantiated for each request, and it is provided to
the template's context as the 'view' varable.
__call__ sets the following:
self.request
self.response
self.context = {}
view.update() is called first. It may do a redirect, additional
checks, or setup information for the template renderer.
If view.render() is defined, it will be run to generate the output.
If its return value is a string (or unicode), self.response.content
will be set to this value. Otherwise its return value will be
returned directly, possibly allowing other Django processors to do
their magic.
If view.render() is not defined, we assume it will be rendered
with a template, so we define a context dictionary, then call
self.render_template.
The context dictionary contains:
'view' : self,
'request' : self.request,
'response' : self.response,
plus anything defined in self.context is merged into the dictionary,
possibly overriding the above variables.
Override render_template(template_name, context_dictionary) to
use an alternate template rendering mechanism.
"""
template = None
context = None
def redirect(self, url):
self.response = http.HttpResponseRedirect(url)
def update(self):
pass
def __call__(self, request, *args, **kwargs):
self.request = request
self.response = http.HttpResponse()
self.update()
if self.response.status_code in (301, 302):
return self.response
if hasattr(self, "render"):
res = self.render()
if isinstance(res, basestring):
self.response.content = res
return self.response
return res
elif self.template:
template = self.template
context = {
'view' : self,
'request' : self.request,
'response' : self.response,
}
extra = getattr(self, 'context', None)
if extra:
context.extend(extra)
r = self.response
r.content = self.render_template(template, context)
return r
else:
if not self.response.content:
self.response.content = 'No Template nor Render Method'
return self.response
def render_template(self, template, context):
"""
Given a template (either a filename to lookup, or an object
with a render() method), lookup the template if necessary, then
wrap the context in a RequestContext and call
template.render(context)
"""
if isinstance(template, basestring):
template = get_template(template)
return template.render(RequestContext(self.request, context))
### example view
class testview(View):
template = "testview.html"
def update(self):
self.age = 29
self.context["nose"] = "normal sized"
self.response["X-Crazy"] = "Maybe"
if self.request.GET.get('next'):
self.redirect(self.request.GET['next'])
def name(self):
return "Robert"
class testview2(View):
template = "testview.html"
def render(self):
return "No template will be used here automatically"
### testview.html:
Hello {{ view.name }}! You are {{ view.age }} years old.
You have a {{ nose }} nose.
|
Comments