下面我将详细讲解"获取Django项目的全部url方法详解"。
前言
在工作中我们经常需要获取Django项目的所有url链接,不仅仅是我们自己定义的url链接,还包括Django内部自带的url链接。这个需求,在做网站地图,爬虫等一些特定的业务逻辑开发中非常常见,本文就是要解决如何获取Django项目的所有url。
获取方式
获取Django项目的所有url链接有多种方式,我这里列举了3种。
方式一:使用第三方库django-extensions
django-extensions是Django的一个第三方扩展库,提供了许多有用的工具。其中一个工具就是show_urls
命令。可以列出所有当前Django项目的url链接。
- 安装django-extensions
python
pip install django-extensions
- 在settings.py中添加django-extensions模块
python
INSTALLED_APPS = [
# ...
'django_extensions',
]
- 运行
show_urls
命令
python
python manage.py show_urls
运行结果每一行包含请求方法,url链接和视图函数名。
python
GET / django.views.generic.base.RedirectView
HEAD / django.views.generic.base.RedirectView
GET /admin/login/ django.contrib.auth.views.LoginView
方式二:使用自定义命令
-
在Django项目的根目录下,创建
urls_inspect.py
文件。 -
在
urls_inspect.py
文件添加以下代码:
```python
from django.core.management.base import BaseCommand
from django.urls import URLPattern, URLResolver
def enumerate_urls(urlpatterns, parent_regex = ""):
for pattern in urlpatterns:
regex = "{}{}".format(parent_regex, pattern.pattern.regex.pattern if isinstance(pattern.pattern, URLPattern) else "")
print(f"{pattern.callback} has regex {regex}")
if isinstance(pattern, URLResolver):
enumerate_urls(pattern.url_patterns, regex)
class Command(BaseCommand):
def handle(self, args, *options):
root_urlconf = import(self.settings['ROOT_URLCONF'], {}, {}, [''])
urlpatterns = root_urlconf.urls.urlpatterns
enumerate_urls(urlpatterns)
```
-
在
settings.py
的INSTALLED_APPS
中添加自定义命令的位置,比如这里的myapp
就是自定义命令所在的位置。python
INSTALLED_APPS = [
# ...
'myapp',
] -
运行自定义命令。
python
python manage.py urls_inspect
命令行输出所有的URL路径(以及相应的视图函数名)。
python
myapp.views.index has regex /
myapp.views.foo has regex /foo/
myapp.views.bar has regex /blah/blubb/
方式三:使用递归遍历url链表
- 在自己的项目中创建
url_inspect
函数,递归遍历url链表。
```python
from django.urls.resolvers import RegexURLPattern, RegexURLResolver
from django.conf.urls import url
import re
urlpatterns = [
url(r'^$', some_view, name='home'),
url(r'^account/$', account_view, name='account'),
url(r'^blog/', include('blog.urls')),
]
def get_urls(urllist, prev=None, namespace=None):
"""
递归遍历url链表,输出所有url结构和名称
"""
for entry in urllist:
if isinstance(entry, RegexURLResolver):
# 如果是一个子url
try:
next_ns = entry.namespace
except ImportError:
# 如果存在ImportError,设置一个默认的namespace
next_ns = None
if entry.urlconf_name:
next_module = import_module(entry.urlconf_name)
patterns = getattr(next_module, 'urlpatterns', next_module)
if isinstance(namespace, str):
next_ns = f"{namespace}:{entry.namespace}"
elif namespace:
next_ns = entry.namespace
else:
next_ns = entry.namespace
get_urls(patterns, entry, namespace=next_ns)
else:
get_urls(entry.url_patterns, entry, namespace=next_ns)
else:
pattern = entry.pattern.regex.pattern
if isinstance(entry, RegexURLPattern):
if prev:
url = f"{prev.pattern.regex.pattern.strip('^/$')}^{pattern.strip('^/$')}"
else:
url = pattern
name = entry.name
if namespace:
name = f"{namespace}:{name}"
print(f"{url:<50s} {name}")
get_urls(urlpatterns)
```
- 运行文件,将遍历打印出来的URL。
python
/ home
/account/ account
/blog/ blog:blog_index
/blog/category/<slug:category_slug>/ blog:list_by_category
/blog/tag/<slug:tag_slug>/ blog:list_by_tag
总结
通过以上三种方式,我们可以很方便地获取Django项目中的所有URL链接,并用于我们的业务逻辑中。其中使用django-extensions的方法最为简单,而自定义命令则更加灵活。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:获取Django项目的全部url方法详解 - Python技术站