在Django中如何基于预设变量仅暴露特定范围的URL?
Django 按序号阈值限制URL访问实现方案
核心逻辑:通过捕获URL中的序号参数,和预设阈值对比,超过阈值直接返回404。
步骤1:预设阈值
首先在项目settings.py中添加全局阈值配置(后续可直接对接admin后台的动态配置,无需修改现有逻辑):
# settings.py MAX_AVAILABLE_METADATA = 25 # 可根据需求修改为任意阈值
步骤2:两种实现方案选其一即可
方案A:自定义路径转换器(URL层直接拦截,性能更高)
适合还未定义对应路由的场景,请求在路由匹配阶段就完成校验,无需进入视图。
- 在你的应用目录下新建
converters.py,写入如下转换器逻辑:
# your_app/converters.py from django.conf import settings from django.http import Http404 class MetadataSeqConverter: regex = r'type(1|2)_(\d+)' def to_python(self, value): # 拆分类型和序号 type_part, seq_part = value.split('_') seq = int(seq_part) # 校验序号是否超过阈值 if seq > settings.MAX_AVAILABLE_METADATA: raise Http404 # 返回解析后的参数给视图 return { 'metadata_type': type_part, 'sequence': seq } def to_url(self, value): # 反向生成URL的逻辑 return f"{value['metadata_type']}_{value['sequence']}"
- 在项目根
urls.py中注册转换器:
# project/urls.py from django.urls import path, register_converter from your_app.converters import MetadataSeqConverter from your_app import views register_converter(MetadataSeqConverter, 'metaseq') urlpatterns = [ # 其他路由... path('metadata/<metaseq:metadata_info>/', views.metadata_access_view, name='metadata_access'), ]
- 视图中可以直接拿到解析后的参数:
# your_app/views.py def metadata_access_view(request, metadata_info): # metadata_info 已经是解析好的字典,如 {'metadata_type': 'type1', 'sequence':1} # 你的业务逻辑
方案B:视图层校验(改造成本更低)
适合已经写好对应路由和视图的场景,直接在视图中添加校验逻辑即可。
- 首先在
urls.py中用正则匹配捕获参数:
# project/urls.py urlpatterns = [ # 其他路由... path('metadata/<str:metadata_type>_<int:sequence>/', views.metadata_access_view, name='metadata_access'), ]
- 在视图中添加阈值校验:
# your_app/views.py from django.conf import settings from django.http import Http404 def metadata_access_view(request, metadata_type, sequence): # 仅允许type1、type2两种类型 if metadata_type not in ['type1', 'type2']: raise Http404 # 校验序号是否超过阈值 if sequence > settings.MAX_AVAILABLE_METADATA: raise Http404 # 你的业务逻辑
效果验证
当阈值设置为25时:
- 访问
/metadata/type1_25/、/metadata/type2_25/可正常进入业务逻辑 - 访问
/metadata/type1_26/、/metadata/type2_10000/会直接返回404响应
如果后续需要通过Django admin动态修改阈值,只需要将阈值存储到数据库的配置表中,校验时从数据库读取配置替换掉settings中的读取逻辑即可,现有校验逻辑无需大幅调整。
内容的提问来源于stack exchange,提问作者jdero
相关产品推荐
相关产品推荐

