在 Django 中,如何获取 URI 解析到的基于 class 的视图的实例?
In Django, how can I get an instance of the class-based-view that a URI resolves to?
我正在开发一个导航系统,我需要从指向它的 URI 中获取 class based view
。
我现在正在使用 resolve('/path/to/whatever/')
获取 ResolverMatch。 ResolverMatch 有一个字典项 func
,它仅作为可调用函数而不是对象链接到 class based view
。
ResolverMatch(func=catalog.views.ThingDetail, args=(), kwargs={'id': '99'}, url_name=thing_detail, app_names=[], namespaces=[])
不过,我需要的是作为对象的对象。我正在通过使用 inspect
获取 func
方法的对象来破解它,但似乎应该有更好的方法。
以下应该可以让您获得视图 class 及其实例(如果需要):
import importlib
rm = resolve('/path/to/whatever/') # ResolverMatch
module_name = rm.func.__module__ # 'path.to.views'
view_name = rm.func.func_name #'FooView'
views = importlib.import_module(module_name)
# <module 'path.to.views' from '/path/to/project_root/path/to/views.pyc'>
view_klass = getattr(views, view_name)
# <class 'path.to.views.FooView'>
view_instance = view_klass()
# <path.to.views.FooView object at 0x7fe2219528d0>
但是请注意,不可能以这种方式获取将用于特定请求的实例,因为视图 class 仅在 rm.func
时实例化 - 可调用 return by View.as_view()
- 被调用。
@classonlymethod
def as_view(cls, **initkwargs):
...
def view(request, *args, **kwargs):
# See: view cls is only instantiated when 'view' is called
self = cls(**initkwargs)
...
return self.dispatch(request, *args, **kwargs)
...
return view
我发现有一个 属性 resolver_match.func.view_class
,我可以调用 resolver_match.func.view_class()
来获取基于 class 的视图的实例。
感谢@schwobaseggl 指出 resolver_match.func
是一个具有属性的对象。具有 class function
的对象具有属性,这既奇怪又令人惊讶。
我正在开发一个导航系统,我需要从指向它的 URI 中获取 class based view
。
我现在正在使用 resolve('/path/to/whatever/')
获取 ResolverMatch。 ResolverMatch 有一个字典项 func
,它仅作为可调用函数而不是对象链接到 class based view
。
ResolverMatch(func=catalog.views.ThingDetail, args=(), kwargs={'id': '99'}, url_name=thing_detail, app_names=[], namespaces=[])
不过,我需要的是作为对象的对象。我正在通过使用 inspect
获取 func
方法的对象来破解它,但似乎应该有更好的方法。
以下应该可以让您获得视图 class 及其实例(如果需要):
import importlib
rm = resolve('/path/to/whatever/') # ResolverMatch
module_name = rm.func.__module__ # 'path.to.views'
view_name = rm.func.func_name #'FooView'
views = importlib.import_module(module_name)
# <module 'path.to.views' from '/path/to/project_root/path/to/views.pyc'>
view_klass = getattr(views, view_name)
# <class 'path.to.views.FooView'>
view_instance = view_klass()
# <path.to.views.FooView object at 0x7fe2219528d0>
但是请注意,不可能以这种方式获取将用于特定请求的实例,因为视图 class 仅在 rm.func
时实例化 - 可调用 return by View.as_view()
- 被调用。
@classonlymethod
def as_view(cls, **initkwargs):
...
def view(request, *args, **kwargs):
# See: view cls is only instantiated when 'view' is called
self = cls(**initkwargs)
...
return self.dispatch(request, *args, **kwargs)
...
return view
我发现有一个 属性 resolver_match.func.view_class
,我可以调用 resolver_match.func.view_class()
来获取基于 class 的视图的实例。
感谢@schwobaseggl 指出 resolver_match.func
是一个具有属性的对象。具有 class function
的对象具有属性,这既奇怪又令人惊讶。