【Dv3Admin】Django一键配置自定义菜单

自动生成权限或菜单时,接口清单不完整或混入基础接口,常见表现为权限漂移、功能入口误配、运维反复回滚。

本文围绕 swagger 文档拉取与动作接口提取链路拆解,聚焦地址拼装、正则匹配、过滤规则、输出结构。

文章目录

需求解析

材料包含两段能力:从本机启动的 Django 服务拉取 swagger.json 原始文本;从 swagger.json 文本中提取动作接口路径并生成动作数据结构。

项目 内容
运行环境 本机启动的 Django 服务
文档入口 swagger.json
输入参数 host、port、app_name、component_name
输出目标 动作接口清单,包含动作名、接口路径、请求方式映射值

动作提取
文档获取
确认服务地址
拉取接口文档
匹配接口路径
识别请求方式
剔除基础接口
组装动作数据

页面支持直接配置端口权限,并配合去重规则,将基础功能与视图动作接口集中完成配置。

功能实现

定位对象 fetch_swagger_text。目的拼出 swagger.json 地址并拉取原始文本,作为解析输入。

python 复制代码
def fetch_swagger_text(host=None, port=None):
    """
    从本机启动的 Django 服务拉取 swagger.json 原始文本
    """
    host = host or '127.0.0.1'
    port = port or os.environ.get('PORT', '8000')
    url = f'http://{host}:{port}/swagger.json'
    resp = requests.get(url)
    resp.raise_for_status()
    return resp.text

需要注意的是 raise_for_status() 属于硬失败策略,服务未启动或路由未暴露会直接抛错中断链路。

定位对象 extract_action_paths。目的从 swagger.json 文本提取动作接口路径与请求方式,剔除基础接口并生成动作数据结构。

python 复制代码
def extract_action_paths(swagger_text, app_name, component_name):
    """
    用正则从 swagger.json 文本中提取所有 /api/{app}/{comp}/<action> 接口
    并剔除基础的 CRUD、import_data、export_data
    返回格式为 [('/api/.../path/', 'get'), ...]
    """
    prefix = re.escape(f'/api/{app_name}/{component_name}/')
    # 匹配路径及请求方法,示例:"paths":{"/api/.../foo/":{"get":{...},...}, ...}
    pattern = rf'"({prefix}[^"]+?)"\s*:\s*\{{\s*"(get|post|put|patch|delete)"'
    matches = re.findall(pattern, swagger_text, flags=re.IGNORECASE)
    seen = set()
    actions = []
    base_suffixes = {'', '{id}/', 'import_data/', 'export_data/'}
    for full_path, method in matches:
        # 只截 actionName/ 或 actionName/{id}/
        suffix = full_path.replace(f'/api/{app_name}/{component_name}/', '')
        # 剔除基础接口
        if any(suffix.startswith(bs) for bs in base_suffixes):
            continue
        key = (full_path, method.lower())
        if key not in seen:
            seen.add(key)
            action = suffix.rstrip('/').split('/')[0]
            actions.append({
                'menu': None,  # 后续在调用处填入 menu_obj.id
                'name': action,
                'value': f'{app_name.replace("/", ":")}:{component_name}:{action.capitalize()}',
                'api': full_path + '/',  # 保持末尾 /
                'method': {'get': 0, 'post': 1, 'put': 2, 'patch': 2, 'delete': 3}[method.lower()]
            })
    return actions

用于明确提取动作接口时的入参边界,三者共同决定匹配前缀与解析范围,任意一项不准确都会导致匹配为空或误匹配到其他模块接口。

参数 含义 约束
swagger_text swagger.json 原始文本 必须为完整文本
app_name 应用名 用于拼接接口前缀
component_name 组件名 用于拼接接口前缀

用于锁定需要剔除的基础接口类型,目标是只保留视图动作类接口,避免 CRUD、导入导出等通用端点混入动作清单,引发权限配置膨胀或入口误挂载。

过滤项 说明
资源集合基础接口 组件根路径对应的基础资源入口
单条资源基础接口 带记录标识的基础资源入口
导入接口 import_data 对应的数据导入入口
导出接口 export_data 对应的数据导出入口

用于定义请求方式到权限系统内部枚举值的映射规则,映射保持稳定才能保证同一接口在不同环境生成出的权限记录一致,否则会出现同路径不同 method 值导致的重复或覆盖。

请求方式 method 映射值
get 0
post 1
put 2
patch 2
delete 3

用于描述最终动作数据结构的字段口径,menu 负责绑定页面入口,name 与 value 承担动作标识与展示编码,api 与 method 决定权限命中条件,需要注意的是 api 末尾斜杠统一处理用于减少路径差异带来的匹配失败。

输出字段 含义 关键约束
menu 菜单标识 初始为 None,调用侧补齐
name 动作名 取路径后缀的首段
value 动作编码 app_name 会做分隔符替换
api 接口路径 末尾补 /
method 请求方式映射 由请求方式映射表生成

这一步不能省略去重逻辑,否则会导致同一路径与同一请求方式在不同匹配场景下重复入库或重复展示。

总结

该实现将接口文档获取与动作接口提取拆为两段,前段只负责稳定获取 swagger 原文,后段集中处理匹配、过滤与结构化输出,边界清晰。

风险集中在正则匹配与路径规范,文档结构变化、路径末尾斜杠差异、基础接口后缀新增,都会导致动作清单偏差,过滤集合需要随接口约定同步维护。

该链路可复用在权限生成、菜单注册、接口盘点场景,价值体现在清单稳定性、维护成本可控、权限口径一致性更容易落地。

相关推荐
wusp19943 小时前
Django 迁移系统全指南:从模型到数据库的魔法之路
数据库·mysql·django
飞天小蜈蚣21 小时前
django的模板渲染、for循环标签、继承模板
数据库·python·django
kobe_OKOK_1 天前
快递鸟对接发快递后端设计系统
python·django
luoluoal1 天前
基于python图像信息隐藏技术设计(源码+文档)
python·mysql·django·毕业设计·源码
wa的一声哭了1 天前
赋范空间 赋范空间的完备性
python·线性代数·算法·机器学习·数学建模·矩阵·django
叫我:松哥2 天前
基于django的新能源汽车租赁推荐分析系统,包括用户、商家、管理员三个角色,协同过滤+基于内容、用户画像的融合算法推荐
python·算法·机器学习·pycharm·django·汽车·echarts
大叔_爱编程2 天前
基于深度神经网络的课程教学评价系统-django
django·毕业设计·tensorflow·源码·scikit-learn·课程设计·深度神经网络
kobe_OKOK_2 天前
tdeinge REST API 客户端
python·缓存·django
Blossom.1183 天前
Prompt工程与思维链优化实战:从零构建动态Few-Shot与CoT推理引擎
人工智能·分布式·python·智能手机·django·prompt·边缘计算