from django.conf import settings
from django.core.urlresolvers import RegexURLResolver, RegexURLPattern
root_urlconf = __import__(settings.ROOT_URLCONF) # import root_urlconf module
all_urlpatterns = root_urlconf.urls.urlpatterns # project's urlpatterns
VIEW_NAMES = [] # maintain a global list
def get_all_view_names(urlpatterns):
global VIEW_NAMES
for pattern in urlpatterns:
if isinstance(pattern, RegexURLResolver):
get_all_view_names(pattern.url_patterns) # call this function recursively
elif isinstance(pattern, RegexURLPattern):
view_name = pattern.callback.func_name # get the view name
VIEW_NAMES.append(view_name) # add the view to the global list
return VIEW_NAMES
get_all_view_names(all_urlpatterns)
from my_app.urls import urlpatterns as my_app_urlpatterns # import urlpatterns of the app
my_app_views = get_all_view_names(my_app_urlpatterns) # call the function with app's urlpatterns as the argument
all_urlpatterns = __import__(settings.ROOT_URLCONF).urls.urlpatterns
detail_views_list = []
def get_all_view_names(urlpatterns):
for pattern in urlpatterns:
if isinstance(pattern, RegexURLResolver):
get_all_view_names(pattern.url_patterns)
elif isinstance(pattern, RegexURLPattern):
detail_views_list.append(pattern.callback.__name__)
get_all_view_names(all_urlpatterns)
all_views_list = []
# remove redundant entries and specific ones we don't care about
for each in detail_views_list:
if each not in "serve add_view change_view changelist_view history_view delete_view RedirectView":
if each not in all_views_list:
all_views_list.append(each)
from importlib import import_module
import inspect
from pathlib import Path
import importlib.util
from django.conf import settings
from django.contrib.admin.options import ModelAdmin
from django.urls import URLResolver, URLPattern
def is_modeladmin_view(view):
"""Return True if the view is an admin view."""
view = inspect.unwrap(view) # In case this is a decorated view
self = getattr(view, "__self__", None)
return self is not None and isinstance(self, ModelAdmin)
def get_all_views(urlpatterns):
"""Given a URLconf, return a set of all view objects."""
views = set()
for pattern in urlpatterns:
if hasattr(pattern, "url_patterns"):
views |= get_all_views(pattern.url_patterns)
else:
if hasattr(pattern.callback, "cls"):
view = pattern.callback.cls
elif hasattr(pattern.callback, "view_class"):
view = pattern.callback.view_class
else:
view = pattern.callback
if not is_modeladmin_view(view):
views.add(view)
return views
def get_module_path(module_name):
"""Return the path for a given module name."""
spec = importlib.util.find_spec(module_name)
if spec is None:
raise ImportError(f"Module '{module_name}' not found")
return Path(spec.origin).resolve()
def is_subpath(path, directory):
"""Return True if path is below directory and isn't within a "venv"."""
try:
path.relative_to(directory)
except ValueError:
return False
else:
# Return True if view isn't under a directory ending in "venv"
return not any(p.endswith("venv") for p in path.parts)
def get_all_local_views():
"""Return a set of all local views in this project."""
root_urlconf = import_module(settings.ROOT_URLCONF)
all_urlpatterns = root_urlconf.urlpatterns
try:
root_directory = settings.ROOT_DIR
except AttributeError:
root_directory = Path.cwd() # Assume we're in the root directory
return {
view
for view in get_all_views(all_urlpatterns)
if is_subpath(get_module_path(view.__module__), root_directory)
}
all_views = get_all_local_views()
print("Number of local views:", len(all_views))
4条答案
按热度按时间am46iovg1#
获取Django项目所有视图列表:
为了获取Django项目中存在的所有视图,我们创建了一个函数
get_all_view_names()
,它将urlpatterns
作为输入,并将项目中使用的完整视图列表作为输出返回。首先,我们使用
settings.ROOT_URLCONF
导入root_urlconf
模块。然后root_urlconf.urls.urlpatterns
将为我们提供项目的urlpatterns列表。上面的urlpatterns列表包含
RegexURLPattern
和RegexURLResolver
对象。在RegexURLResolver
上访问.urlpatterns
将进一步为我们提供RegexURLPattern
和RegexURLResolver
对象的列表。**
RegexURLPattern
对象将给予我们感兴趣的视图名称。**其上的callback
属性包含可调用视图。当我们在url中传递一个字符串(如'foo_app.views.view_name'
)表示模块的路径和视图函数名称时,或者传递一个可调用视图时,然后callback
属性被设置为这个。进一步访问.func_name
将给予我们视图名称。我们递归调用函数
get_all_view_names()
,并将从RegexURLPattern
对象获得的视图名称添加到全局列表VIEW_NAMES
中。获取Django应用中所有视图列表:
要获取Django应用程序中所有视图的列表,我们将使用上面定义的
get_all_view_names()
函数。我们将首先导入应用程序的所有
urlpatterns
,并将此列表传递给get_all_view_names()
函数。my_app_views
为我们提供了my_app
Django应用程序中所有视图的列表。o0lyfsai2#
添加到Rahul的上述修复中,如果有人使用***Python3***,则需要使用
__name__
而不是func_name
:否则,您将得到以下内容:
(感谢www.example.com上的scipy-gitbothttps://github.com/scipy/scipy/issues/2101#issuecomment-17027406
作为替代,如果你不愿意使用全局变量,下面是我最终使用的:
然后,您可以遍历
all_views_list
以获得过滤后的视图列表。更新:2018年3月1日
在Django 2.0中,
django.core.urlresolvers
被移动到django.urls
。RegexURLPattern
和RegexURLResolver
被重命名为URLPattern
和URLResolver
。所以你应该使用代替
如果你使用Django 2。
roqulrg33#
使用全局变量获取所有Django和DRF视图
xqk2d5yq4#
我需要计算我的项目. Here's code that does that的本地视图数。
这与目前的答案不同,因为:
ModelAdmin
类下的视图get_all_local_views
函数只返回当前目录(或settings.ROOT_DIR
下)中不在venv
目录下的视图