django-CBV
- FBV : 基于函数的视图
- CBV : 基于类的视图
CBV类的基类View
class View:
"""
"""
# 定义 请求的方式
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
def __init__(self, **kwargs):
"""
构建View对象,将格外传过来的字典中的键作为 View对象的属性, value作为属性值
"""
# Go through keyword arguments, and either save their values to our
# instance, or raise an error.
for key, value in kwargs.items():
setattr(self, key, value)
@classonlymethod
def as_view(cls, **initkwargs):
"""
as_view 是将 视图类 转换为 视图函数
"""
for key in initkwargs:
# as_view 传过来的额外参数 不能是 http_method_names 定义的名字
if key in cls.http_method_names:
raise TypeError(
'The method name %s is not accepted as a keyword argument '
'to %s().' % (key, cls.__name__)
)
# as_view 传过来的额外参数 不能是 View对象的属性 或者 方法
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):
"""
处理业务、返回 HttpResponse
"""
# 初始化 View对象
self = cls(**initkwargs)
# 将 request, args, kwargs 赋值给 当前 View对象
self.setup(request, *args, **kwargs)
if not hasattr(self, 'request'):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
# 通过请求方式名 或者 View对象的 方法名,并调用方法、返回HttpResponse
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=())
return view
def setup(self, request, *args, **kwargs):
"""Initialize attributes shared by all view methods."""
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
def dispatch(self, request, *args, **kwargs):
"""
将 请求 分发给 对应的 请求方法
"""
if request.method.lower() in self.http_method_names:
# 获取 View对象 和 请求方法名 相同 方法
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 调用 视图函数、完成业务处理
return handler(request, *args, **kwargs)
def http_method_not_allowed(self, request, *args, **kwargs):
"""
405 请求方法不允许
"""
logger.warning(
'Method Not Allowed (%s): %s', request.method, request.path,
extra={'status_code': 405, 'request': request}
)
return HttpResponseNotAllowed(self._allowed_methods())
def options(self, request, *args, **kwargs):
"""
获取允许的所有请求方法
"""
"""Handle responding to requests for the OPTIONS HTTP verb."""
response = HttpResponse()
response['Allow'] = ', '.join(self._allowed_methods())
response['Content-Length'] = '0'
return response
def _allowed_methods(self):
"""
获取当前 View 允许的所有请求方法、并转为大写
"""
return [m.upper() for m in self.http_method_names if hasattr(self, m)]
通用视图
- ListView
- DetailView
- CreateView
- DeleteView
- UpdateView
get_queryset()
根据 queryset 或者 model 查询 对应模型的所有数据
通过 ordering 进行排序