路径参数验证终极指南:系统自带 vs 自定义转换器

举报
周杰伦本人 发表于 2025/08/31 20:36:01 2025/08/31
【摘要】 路径参数验证终极指南:系统自带 vs 自定义转换器 一、为什么需要验证用户可以在浏览器地址栏随意输入:/shop/abc、/product/xyz。如果不加验证,视图直接拿字符串去查库,要么 404,要么 SQL 报错。因此路径参数必须“先过滤、后使用”。 二、两条技术路线方式位置优点缺点视图函数内正则views .py简单直观代码重复,复用性差自定义转换器urls .py全局复用,统一格...

路径参数验证终极指南:系统自带 vs 自定义转换器

一、为什么需要验证

用户可以在浏览器地址栏随意输入:/shop/abc/product/xyz。如果不加验证,视图直接拿字符串去查库,要么 404,要么 SQL 报错。因此路径参数必须“先过滤、后使用”

二、两条技术路线

方式 位置 优点 缺点
视图函数内正则 views .py 简单直观 代码重复,复用性差
自定义转换器 urls .py 全局复用,统一格式 需 3 步(定义-注册-使用)

三、系统自带转换器速查
Django 内置 5 个,开箱即用:

  • int:≥0 整数;path('item/<int:pk>/')

  • str:除 / 外任意字符(默认);path('slug/<str:title>/')

  • slug:ASCII 字母、数字、连字符、下划线

  • uuid:标准 UUID 格式

  • path:可含 / 的字符串,例如 /2023/08/12/

使用规则:

path('shop/<int:city_id>/<int:shop_id>/', views.shop)

浏览器输入 /shop/11000/11005/ → 视图收到 city_id=11000, shop_id=11005;输入 /shop/abc/ 直接 404。

四、自定义转换器 3 步曲
以“11 位手机号”为例:

1️⃣ 定义类

# book/converters.py
import re
from django.urls.converters import StringConverter

class MobileConverter(StringConverter):
    regex = r'^1[3-9]\d{9}$'        # 匹配 1 开头 11 位数字
    def to_python(self, value):
        return int(value)           # 转成 int
    def to_url(self, value):
        return str(value)           # 反向解析用

2️⃣ 注册

# book/urls.py
from django.urls import register_converter
from .converters import MobileConverter

register_converter(MobileConverter, 'mobile')   # 别名 mobile

3️⃣ 使用

path('city/<int:city_id>/shop/<mobile:phone>/', views.shop_by_phone)

效果:

  • /city/1100/shop/13312341234/ → 视图收到 city_id=1100, phone=13312341234

  • /city/1100/shop/123/ → 404(正则不匹配)

五、完整示例:手机号 + 城市

# urls.py
from django.urls import path, register_converter
from book import views, converters

register_converter(converters.MobileConverter, 'mobile')

urlpatterns = [
    path('shop/<int:city_id>/<mobile:phone>/', views.shop_detail),
]

# views.py
def shop_detail(request, city_id, phone):
    try:
        shop = Shop.objects.get(city_id=city_id, phone=phone)
        return HttpResponse(f"{shop.name} 欢迎你!")
    except Shop.DoesNotExist:
        return HttpResponse("门店不存在", status=404)

六、常见问题 FAQ

  1. 404 还是 500?
    转换器不匹配 → 404;匹配后视图逻辑错误 → 500。

  2. 顺序要求
    register_converter 必须放在 urlpatterns 之前,否则启动时报 Invalid converter

  3. 反向解析
    reverse('shop', args=[1100, 13312341234]) 自动用 to_url 方法生成正确 URL。

  4. 复用场景
    多个 APP 共享手机号、身份证号、统一社会信用代码等格式,都可写成独立转换器,一处注册,全局使用。

七、调试技巧
在视图里打印参数类型:

print(type(city_id), city_id, type(phone), phone)

确认转换器生效后,再进行后续业务逻辑。

八、一句话总结
“路径参数先过滤、后使用;内置转换器够用就用,不够用就自定义三步:定义类 → 注册 → 路由 <转换器:变量>。”

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。