关键词

获取Django项目的全部url方法详解

下面我将详细讲解"获取Django项目的全部url方法详解"。

前言

在工作中我们经常需要获取Django项目的所有url链接,不仅仅是我们自己定义的url链接,还包括Django内部自带的url链接。这个需求,在做网站地图,爬虫等一些特定的业务逻辑开发中非常常见,本文就是要解决如何获取Django项目的所有url。

获取方式

获取Django项目的所有url链接有多种方式,我这里列举了3种。

方式一:使用第三方库django-extensions

django-extensions是Django的一个第三方扩展库,提供了许多有用的工具。其中一个工具就是show_urls命令。可以列出所有当前Django项目的url链接。

  1. 安装django-extensions

python
pip install django-extensions

  1. 在settings.py中添加django-extensions模块

python
INSTALLED_APPS = [
# ...
'django_extensions',
]

  1. 运行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

方式二:使用自定义命令

  1. 在Django项目的根目录下,创建urls_inspect.py文件。

  2. 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)
```

  1. settings.pyINSTALLED_APPS中添加自定义命令的位置,比如这里的myapp就是自定义命令所在的位置。

    python
    INSTALLED_APPS = [
    # ...
    'myapp',
    ]

  2. 运行自定义命令。

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链表

  1. 在自己的项目中创建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)
```

  1. 运行文件,将遍历打印出来的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的方法最为简单,而自定义命令则更加灵活。

本文链接:http://task.lmcjl.com/news/14400.html

展开阅读全文