def check_url_exclude(url):
"""
判断url是否需要自动被发现,如果不是则移除
:param url: 自动发现的url
:return: bool
"""
for regex in settings.AUTO_DISCOVER_EXCLUDE:
if re.match(regex, url):
return True
def recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict):
"""
递归的去获取URL
:param pre_namespace: namespace前缀,以后用户拼接name
:param pre_url: url前缀,以后用于拼接url
:param urlpatterns: 路由关系列表
:param url_ordered_dict: 用于保存递归中获取的所有路由
:return:
"""
for item in urlpatterns:
if isinstance(item, URLPattern): # 非路由分发,讲路由添加到url_ordered_dict
if not item.name:
continue
# 如果上层有namespace,则拼接rbac:name,反之则只使用自己的name
name = f"{pre_namespace}:{item.name}" if pre_namespace else item.name
# url = pre_url + item.pattern.regex.pattern # /rbac/user/edit/(?P<pk>\d+)/
url = pre_url + str(item.pattern) # /rbac/user/edit/(?P<pk>\d+)/
url = url.replace('^', '').replace('$', '')
if check_url_exclude(url):
continue
url_ordered_dict[name] = {'name': name, 'url': url}
elif isinstance(item, URLResolver): # 路由分发,递归操作
if pre_namespace:
if item.namespace:
namespace = "%s:%s" % (pre_namespace, item.namespace,)
else:
namespace = pre_namespace
else:
# 如果自己的namespace存在,就用给自己的,如果自己没有则为None
namespace = item.namespace or None
recursion_urls(namespace, pre_url + str(item.pattern), item.url_patterns, url_ordered_dict)
def get_all_url_dict():
"""
获取项目中所有的URL(必须有name别名)
:return:
"""
url_ordered_dict = OrderedDict()
md = import_string(settings.ROOT_URLCONF) # from luff.. import urls
recursion_urls(None, '/', md.urlpatterns, url_ordered_dict) # 递归去获取所有的路由
return url_ordered_dict