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
View Code
#!/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
2.0

 

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')
posted @ 2022-04-06 02:35  silencio。  阅读(58)  评论(0编辑  收藏  举报