问题
Is there any way to get a list of all views in an django app? I have googled for answer. All answers shows a way to get list of urls.
回答1:
Getting list of all the views of a Django project:
To get all the views present in a Django project, we create a function get_all_view_names()
which takes urlpatterns
as input and returns the complete list of views being used in the project as the output.
First, we import the root_urlconf
module using settings.ROOT_URLCONF
. Then root_urlconf.urls.urlpatterns
will give us the list of project's urlpatterns.
The above urlpatterns list contains RegexURLPattern
and RegexURLResolver
objects. Accessing .urlpatterns
on a RegexURLResolver
will further give us a list of RegexURLPattern
and RegexURLResolver
objects.
A RegexURLPattern
object will give us the view name which we are interested in. The callback
attribute on it contains the callable view. When we pass either a string in our urls like 'foo_app.views.view_name'
representing the path to a module and a view function name, or a callable view, then callback
attribute is set to this. Further accessing .func_name
will give us the view name.
We call the function get_all_view_names()
recursively and add the view names obtained from a RegexURLPattern
object to a global list VIEW_NAMES
.
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)
Getting list of all the views in a Django application:
To get the list of all the views present in a Django application, we will use the get_all_view_names()
function defined above.
We will first import all the urlpatterns
of the application and pass this list to the get_all_view_names()
function.
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
my_app_views
gives us the list of all the views present in my_app
Django app.
回答2:
Adding on to above fix by Rahul, if anyone is using Python3, you will need to use __name__
instead of func_name
:
...
view_name = pattern.callback.__name__
...
otherwise you will get the following:
AttributeError: 'function' object has no attribute 'get_all_view_names'
(Thanks to scipy-gitbot at https://github.com/scipy/scipy/issues/2101#issuecomment-17027406
As an alternative, if you are disinclined to using global variables, here is what I ended up using :
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)
Then you can just iterate through all_views_list
to get the list of filtered views.
update: Mar 1 2018
In Django 2.0, django.core.urlresolvers
is moved to django.urls
. RegexURLPattern
and RegexURLResolver
are renamed to URLPattern
and URLResolver
. So you should use
from django.urls import URLResolver, URLPattern
instead of
from django.core.urlresolvers import RegexURLResolver, RegexURLPattern
if you are using Django 2.
来源:https://stackoverflow.com/questions/32933229/how-to-get-a-list-of-all-views-in-a-django-application