一、django 1 版本
routers.py
import refrom collections import OrderedDictfrom django.conf import settingsfrom django.utils.module_loading import import_string ?# 根据字符串的形式,帮我们去导入模块from django.urls import RegexURLResolver, RegexURLPattern # 路由分发:URLResolver。不是路由分发:URLPatterndef check_url_exclude(url): ???""" ???排除一些特定的url ???:param url: ???:return: ???""" ???exclude_url = [ ???????‘/admin.*‘, ???????‘/login/‘ ???] ???for regex in settings.AUTO_DISCOVER_EXCLUDE: ???????if re.match(regex, url): ???????????return Truedef recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict): ???""" ???:param pre_namespace: namespace前缀(rbac:......),以后用于拼接name ???:param pre_url: url的前缀(rbac/......),以后用于拼接url ???:param urlpatterns: 路由关系列表 ???:param url_ordered_dict: 用于保存递归中获取的所有路由 ???:return: ???""" ???for item in urlpatterns: ???????if isinstance(item,RegexURLPatter): ?# 非路由分发,将路由添加到url_ordered_dict ???????????if not item.name: ?# url中反向命名的name ???????????????continue ???????????if pre_namespace: ???????????????name = f"{pre_namespace}:{item.name}" ???????????else: ???????????????name = item.name ???????????url = pre_url + item.item._regex ?# /^rbac/^user/edit/(?P<pk>\d_+)/$ ???????????url = url.replace(‘^‘, ‘‘).replace(‘$‘, ‘‘) ?# /rbac/user/edit/(?P<pk>\d_+)/ ???????????if check_url_exclude(url): ???????????????continue ???????????url_ordered_dict[name] = {‘name‘: name, ‘url‘: url} ???????elif isinstance(item, ?RegexURLResolver): ?# 路由分发,进行递归操作 ???????????if pre_namespace: ???????????????if item.namespace: ???????????????????namespace = f"{pre_namespace}:{item.namespace}" ???????????????else: ???????????????????namespace = item.namespace ???????????else: ???????????????if item.namespace: ???????????????????namespace = item.namespace ???????????????else: ???????????????????namespace = None ???????????recursion_urls(namespace, pre_url + item.regex.pattern, item.url_patterns, url_ordered_dict)def get_all_url_dict(): ???""" ???获取项目中所有的URL(必须有name别名) ???:return: ???""" ???url_ordered_dict = OrderedDict() ???""" ???{ ???????‘rbac:menu_list‘:{name:‘rbac:menu_list‘,url:‘xxxxx/yyyy/menu/list‘} ???} ???""" ???md = import_string(settings.ROOT_URLCONF) ?# from permision_learn import urls ???recursion_urls(None, ‘/‘, md.urlpatterns, url_ordered_dict) ?# 递归的去获取所有的路由。根目录没有namespace,根路由用/ ???return url_ordered_dict
views.py
def multi_permissions(request): ???""" ???批量操作权限 ???:param request: ???:return: ???""" ???# 获取项目中所有的url ???all_url_dict = get_all_url_dict() ???for k, v in all_url_dict.items(): ???????print(k, v) ???return HttpResponse(‘....‘)
二、django 2版本
django 2版本有些坑,和django 1版本的用法略有不同。谷歌查了半天,只查到模块名变了,没查到用法。没办法,只能取看源码,只能看到参数名变了,瞎试了试,居然能用。
routers.py
import refrom collections import OrderedDictfrom django.conf import settingsfrom django.utils.module_loading import import_string ?# 根据字符串的形式,帮我们去导入模块from django.urls import URLPattern, URLResolver ?# 路由分发:URLResolver。不是路由分发:URLPatterndef check_url_exclude(url): ???""" ???排除一些特定的url ???:param url: ???:return: ???""" ???exclude_url = [ ???????‘/admin.*‘, ???????‘/login/‘ ???] ???for regex in settings.AUTO_DISCOVER_EXCLUDE: ???????if re.match(regex, url): ???????????return Truedef recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict): ???""" ???:param pre_namespace: namespace前缀(rbac:......),以后用于拼接name ???:param pre_url: url的前缀(rbac/......),以后用于拼接url ???:param urlpatterns: 路由关系列表 ???:param url_ordered_dict: 用于保存递归中获取的所有路由 ???:return: ???""" ???for item in urlpatterns: ???????if isinstance(item, URLPattern): ?# 非路由分发,将路由添加到url_ordered_dict ???????????if not item.name: ?# url中反向命名的name ???????????????continue ???????????if pre_namespace: ???????????????name = f"{pre_namespace}:{item.name}" ???????????else: ???????????????name = item.name ???????????url = pre_url + item.pattern.regex.pattern ?# /^rbac/^user/edit/(?P<pk>\d_+)/$ ???????????url = url.replace(‘^‘, ‘‘).replace(‘$‘, ‘‘) ?# /rbac/user/edit/(?P<pk>\d_+)/ ???????????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 = f"{pre_namespace}:{item.namespace}" ???????????????else: ???????????????????namespace = item.namespace ???????????else: ???????????????if item.namespace: ???????????????????namespace = item.namespace ???????????????else: ???????????????????namespace = None ???????????recursion_urls(namespace, pre_url + item.pattern.regex.pattern, item.url_patterns, url_ordered_dict)def get_all_url_dict(): ???""" ???获取项目中所有的URL(必须有name别名) ???:return: ???""" ???url_ordered_dict = OrderedDict() ???""" ???{ ???????‘rbac:menu_list‘:{name:‘rbac:menu_list‘,url:‘xxxxx/yyyy/menu/list‘} ???} ???""" ???md = import_string(settings.ROOT_URLCONF) ?# from permision_learn import urls ???recursion_urls(None, ‘/‘, md.urlpatterns, url_ordered_dict) ?# 递归的去获取所有的路由。根目录没有namespace,根路由用/ ???return url_ordered_dict
views.py
def multi_permissions(request): ???""" ???批量操作权限 ???:param request: ???:return: ???""" ???# 获取项目中所有的url ???all_url_dict = get_all_url_dict() ???for k, v in all_url_dict.items(): ???????print(k, v) ???return HttpResponse(‘....‘)
自动发现项目中的URL,django1版本和django2版本
原文地址:https://www.cnblogs.com/lshedward/p/10467931.html