Django3.2 自動發(fā)現(xiàn)所有路由代碼詳解
更新時間:2021年12月03日 15:58:06 作者:GouHuang
這篇文章主要為大家介紹了Django自動發(fā)現(xiàn)所有路由的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
1.需求
發(fā)現(xiàn)項目本地所有帶別名的URL,組成一個有序字典,方便后續(xù)調(diào)用;
定向排除部分URL,如Django自帶的 admin下的路由;
2.代碼實現(xiàn)
import re # 正則
from collections import OrderedDict # 創(chuàng)建有序字典
from django.conf import settings # 導(dǎo)入setting配置文件(獲取項目根路徑urls.py)
from django.utils.module_loading import import_string # 字符串導(dǎo)入模塊
from django.urls import URLPattern, URLResolver # Django自定義的類,可以判斷當(dāng)前URL是否為根路徑(URLPattern)或繼續(xù)向下分發(fā)(URLResolver )
def check_url_exclude(url):
"""
排除一些特定的URL
:param url: 待檢驗的URL
:return:
"""
for regex in settings.AUTO_DISCOVER_EXCLUDE: #將要定向排除的URL(可包含正則) 按照列表的形式寫入配置文件 settings.AUTO_DISCOVER_EXCLUDE 下
if re.match(regex, url):
return True
"""
示例:
AUTO_DISCOVER_EXCLUDE = [
'/admin/.*',
'/login/',
'/logout/',
'/index/',
]
"""
def recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict):
"""
遞歸的去獲取URL
:param pre_namespace: namespace前綴,用于拼接name
:param pre_url: url前綴,用于拼接url
:param urlpatterns: 路由關(guān)系列表
:param url_ordered_dict: 用于保存遞歸中獲取的所有路由
:return:
"""
for item in urlpatterns:
if isinstance(item, URLPattern): # 已經(jīng)是根網(wǎng)址,獲取name及url寫入url_ordered_dict
if not item.name: # 沒有別名(name)的路由地址直接跳過
continue
# 拼接路由別名(包含分發(fā)下來的namespace;如 "rbac:menu_list")
if pre_namespace:
name = "%s:%s" % (pre_namespace, item.name)
else:
name = item.name
# 拼接路由地址URl(包含分發(fā)下來的上層路由;如 "/rbac/menu/list")
url = pre_url + item.pattern.regex.pattern # 此時拼接的路由包含起止符號,如:/^rbac/^menu/list/$
url = url.replace("^", "").replace("$", "") # 刪除起止符:/rbac/menu/list/
# 排除一些特定的路由URL
if check_url_exclude(url): # 調(diào)用check_url_exclude函數(shù)定向排除部分URL
continue
url_ordered_dict[name] = {"name": name, "url": url}
elif isinstance(item, URLResolver): # 路由分發(fā),遞歸操作
if pre_namespace: # 上次循環(huán)(上一層)分發(fā)是否包含namespace
if item.namespace: # 本次循環(huán)(當(dāng)前層)是否包含namespace
namespace = "%s:%s" % (pre_namespace, item.namespace,) # 上層、當(dāng)前層都包含直接拼接兩層的namespace
else:
namespace = pre_namespace # 當(dāng)前層分發(fā)不包含namespace,直接用上一層的
else:
if item.namespace:
namespace = item.namespace # 上一層分發(fā)不包含namespace,直接使用當(dāng)前層的
else:
namespace = None # 上一層、當(dāng)前層都沒有,直接定義層none
recursion_urls(namespace, pre_url + item.pattern.regex.pattern, item.url_patterns, url_ordered_dict) # 遞歸繼續(xù)執(zhí)行
def get_all_url_dict():
"""
獲取項目所有路由
:return:
"""
url_ordered_dict = OrderedDict() # 包含本項目所有權(quán)限URl的有序字典
md = import_string(settings.ROOT_URLCONF) # 配置文件內(nèi)的 ROOT_URLCONF 為本項目根路由urls.py 的路徑(字符串),使用 import_string 用字符串加載模塊
recursion_urls(None, "/", md.urlpatterns, url_ordered_dict) # 調(diào)用 recursion_urls 函數(shù)獲取所有路由字典,根路徑下沒有namespace 定義為 None;沒有url前綴 定義為 /
return url_ordered_dict
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Python標(biāo)準(zhǔn)庫shutil模塊使用方法解析
這篇文章主要介紹了Python標(biāo)準(zhǔn)庫shutil模塊使用方法解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
Python3 Tkinkter + SQLite實現(xiàn)登錄和注冊界面
這篇文章主要為大家詳細介紹了Python3 Tkinkter + SQLite實現(xiàn)登錄和注冊界面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-11-11

