asdfd
as_view in django源码分析
一、基于类的视图
基于函数的视图,我想不用多说了吧。
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r’^$’, views.yourfuncview, name=‘name’)
接下来我们要重点关注的是基于类的视图,看看它是如何使用的
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r’^$’, Home.as_view(), name=‘home’)
二、as_view的源码
总体思路:把视图函数的逻辑定义到类中,再通过继承的View类的as_view类方法返回一个名叫view函数,然后再执行这个view函数,通过在view中实例化自定义的类,再配合从前端的请求方式(get/post)来映射(dispatch)到自定义类的get或者post方法中去。通过类来定义逻辑的好处就是代码重用!!!
@classonlymethod
def as_view(cls, **initkwargs):
"""
Main entry point for a request-response process.
"""
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key))
#2.然后执行这个函数,并传入request,等从前端传过来的参数
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs
# take name and docstring from class
update_wrapper(view, cls, updated=())
# and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
# 1.执行 as_view()后返回了这个view
return view
# 3.最后根据是get、post请求执行对应的定义在自己编写的get、post方法
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
调用顺序: as_view --> view --> dispatch
- 可以看出as_view实际上是一个闭包,他的作用就是做一些检验工作,再返回view方法
- 而view方法的作用是给请求对象补充三个参数,并调用dispatch方法处理
- dispatch方法查找到指定的请求方法,并执行相应代码块
总结
现在我们已经明白了类视图的基本结构,其主要功能就是根据 HTTP 请求方法的不同做出相应处理,具体的实现为 dispatch 方法。类视图的核心思想就是把视图函数的逻辑定义到类的方法里面去,然后在函数中实例化这个类,通过调用类的方法实现函数逻辑。