django2、3 自动发现项目中的url
crm项目修改的
1 url入口:rbac/urls.py
urlpatterns = [ ... # 批量操作权限 re_path(r '^multi/permissions/$' , menu.multi_permissions, name = 'multi_permissions' ) # 自动发现项目中的所有URL ... ] |
2 配置文件 settings
不用发现的url列表: AUTO_DISCOVER_EXCLUDE = [ '/admin/' , '/login/' , ] |
3 自定发现url的组件:rbac/service/router.py#!/usr/bin/env # -*- coding:utf-8 -*-
#!/usr/bin/env python # -*- coding:utf-8 -*- import re from collections import OrderedDict from django.conf import settings from django.utils.module_loading import import_string from django.urls.resolvers import URLResolver, URLPattern # 路由分发:URLResolver。非路由分发:URLPattern def check_url_exclude(url): """ 查看被排除在外的url :param url: :return: """ 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: 用于保存递归中获取的所有的url :return: """ for item in urlpatterns: if isinstance(item, URLPattern): #非路由分发 添加到字典url_ordered_dict中 if not item.name: continue if pre_namespace: name = "%s:%s" % (pre_namespace, item.name) else: name = item.name url = pre_url + item.pattern._route # str(item.pattern) 写法不规范,参考下面的 item.pattern._route<br> url = url.replace("^", "").replace("$", "") if check_url_exclude(url):# 判断是否admin、login等我们不需要的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 = pre_namespace else: if item.namespace: namespace = item.namespace else: namespace = None# 父级没有namespace,自己也没有 recursion_urls(namespace, pre_url+str(item.pattern), item.url_patterns, url_ordered_dict) def get_all_url(): """ 获取所有的url :return: """ url_ordered_dict = OrderedDict() md = import_string(settings.ROOT_URLCONF) # 递归获取所有的url recursion_urls(None, '/', md.urlpatterns, url_ordered_dict) return url_ordered_dict
#!/usr/bin/env python # -*- coding:utf-8 -*- import re from collections import OrderedDict from django.conf import settings from django.utils.module_loading import import_string from django.urls import URLResolver, URLPattern def check_url_exclude(url): """ 排除一些特定的URL :param url: :return: """ 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 if pre_namespace: name = "%s:%s" % (pre_namespace, item.name) else: name = item.name 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: if item.namespace: namespace = item.namespace else: namespace = 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
4 视图函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
from rbac.service.router import get_all_url_dict 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( 'ok it' ) |