基于类的视图对编写RESTful API 比 视图函数 更加方便,在代码层面也更清晰。
下面是个人对基于类的视图浅薄认识,如有不对的地方,还望高台贵手指点一下,抱拳!
示例:
@classonlymethod
def as_view(cls, **initkwargs):
"""Main entry point for a request-response process."""
for key in initkwargs:
# 判断as_view()方法 传入的参数是不是与请求方法重名了,如果重名了抛出异常
if key in cls.http_method_names: # http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
raise TypeError(
'The method name %s is not accepted as a keyword argument '
'to %s().' % (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))
def view(request, *args, **kwargs):
self = cls(**initkwargs) # 对当前类进行实例化
self.setup(request, *args, **kwargs) # 设置实例request/arg/kwarg 属性
if not hasattr(self, 'request'): # 如果实例没有request属性,则抛出异常
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
return self.dispatch(request, *args, **kwargs) # 根据实例的请求方法 来调用类中定义的method函数,如果类中没有定义 则抛出异常
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=())
return view
简单解读:
1.判断参数是否合法
a.参数是否跟http的method命名重复
b.视图类是否已手工定义了相关的属性
2.对视图类进行实例化,判断是否浏览器的请求方法,是否有(视图类是否有定义GET、POST之类的方法),然后返回一个视图函数。
如果给test_class_view.as_view()方法传递参数,那么这个参数必须是test_class_view这个实现了的属性:
class test_class_view(View):
def get(self, request):
return HttpResponse("类视图")
test_key = None # 如果as_view() 传入test_key关键字参数,类中必须定义
如果视图类中不定义as_view()传入的参数对应同名属性: