基于 Django 类的视图:了解视图类中的参数
Posted
技术标签:
【中文标题】基于 Django 类的视图:了解视图类中的参数【英文标题】:Django Class Based Views: Understanding the arguments in the view class 【发布时间】:2015-04-30 11:56:23 【问题描述】:通读View Class
的源代码
源代码:
class View(object):
"""
Intentionally simple parent class for all views. Only implements
dispatch-by-method and simple sanity checking.
"""
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
def __init__(self, **kwargs):
"""
Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.
"""
# Go through keyword arguments, and either save their values to our
# instance, or raise an error.
for key, value in six.iteritems(kwargs):
setattr(self, key, value)
@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))
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=())
return view
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)
def http_method_not_allowed(self, request, *args, **kwargs):
logger.warning('Method Not Allowed (%s): %s', request.method, request.path,
extra=
'status_code': 405,
'request': request
)
return http.HttpResponseNotAllowed(self._allowed_methods())
我的理解是,加载urlconf时,会调用as_view
class only方法。 as_view
调用 view
方法,该方法用 self= cls(**initkwargs)
实例化一个 View 对象,然后 __init__
运行。
我对弄清楚view
方法所采用的**kwargs
与实例化类时使用的**initkwargs
之间的区别感到困惑。我假设view
方法通过**kwargs
传递所有参数...那么为什么self= cls(**initkwargs)
行不写为self = cls(**kwargs)
?
**initkwargs
和 **kwargs
有什么区别?
【问题讨论】:
【参考方案1】:
as_view
调用view
方法,该方法用self= cls(**initkwargs)
实例化View
对象,然后__init__
运行。
实际上不,这没有发生。 as_view
没有调用view
函数(view
不是方法),as_view
创建view
函数并返回它,因此可以稍后调用。 initkwargs
在处理 urlpatterns 时被传递给 as_view
,kwargs
在 URL 调度程序在检索特定 url 时调用它时被传递到视图中。这就是为什么kwargs
和initkwargs
不是一回事。
【讨论】:
**initkwargs
和**kwargs
的值是否不同? URL 调度程序将 view(request, **args, **kwargs)
包含在 URL 中的参数作为 **kwargs 传递,对吗?那么**initkwarg
的值是什么?它们是否也在 URL 中找到?还是它们来自其他地方?
没关系,我明白。例如,可以使用 TemplateView 子类化基本视图类。如果这样做,您可以通过将默认模板名称传递给 as_view 来覆盖它。然后,来自 URL 的参数被进一步添加到视图函数中【参考方案2】:
代码只是明确区分了您从 urlconf 传递到视图类本身的实例化的硬编码 kwargs,以及您在实际调用视图时从 URL 传递的动态 kwargs .
【讨论】:
以上是关于基于 Django 类的视图:了解视图类中的参数的主要内容,如果未能解决你的问题,请参考以下文章
Django后端开发学习笔记Django REST Framework基于类的视图
如何正确地将参数传递给 Django 中的基于类的视图实例?