在django中,view有2种编码形式。
1种是function返回
1种是class返回
分析
views文件夹
views
|----decorators
|----__init__.py
|----cache.py
|----clickjacking.py
|----csrf.py
|----debug.py
|----gzip.py
|----http.py
|----vary.py
|----generic
|----__init__.py
|----base.py
|----dates.py
|----detail.py
|----edit.py
|----list.py
|----__init__.py
|----csrf.py
|----defaults.py
|----i18n.py
|----static.py
对于views目录和decorators目录下的文件,主要是为了封装了一些函数和装饰器,为了方便函数返回response的代码
对于generic目录下的代码。感觉写起来很帅气。利用多重集成实现mvc分离。把数据源获取,模版渲染。拆分开
下面是精简演示代码。具体就不分析了
from functools import update_wrapper
class ContextMixin(object):
def get_context_data(self, **kwargs):
print 'get contenxt'
if 'view' not in kwargs:
kwargs['view'] = self
return kwargs
class View(object):
http_method_names = ['get','post','put','delete']
def __init__(self, **kwargs):
for (k, v) in kwargs.items():
setattr(self, k, v)
@classmethod
def as_view(cls, **initkwargs):
for key in initkwargs:
if key in cls.http_method_names:
raise "can't set httpmethod key"
def view(request, *args, **kwargs):
self = cls(**initkwargs)
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
update_wrapper(view, cls, updated=())
update_wrapper(view, cls.dispatch, updated=())
return view
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower())
else:
raise "Can't dispatch request"
return handler(request, *args, **kwargs)
class TemplateResponseMixin(object):
template_name = None
def render_to_response(self, context, **response_kwargs):
print 'render context:[%s] to html["%s"]' % (context, self.template_name)
class TemplateView(TemplateResponseMixin, ContextMixin, View):
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
class AboutView(TemplateView):
template_name = 'about.html'
class Request(object):
def __init__(self, method = 'get'):
self.method = method
AboutView.as_view(template_name='1.html')(Request())
输出内容为:
get contenxt
render context:[{'view': <__main__.AboutView object at 0x103bd8e10>}] to html["1.html"]