Django使用自定义非pk字段作为URL参数时reverse出现NoReverseMatch报错
问题根因
你遇到的报错是因为Django默认的slug路径转换器的匹配规则仅支持大小写字母、数字、下划线、连字符(对应正则为[-a-zA-Z0-9_]+),但你存储在url字段里的值包含了/、.等字符,不在匹配范围内,因此反向生成URL时无法匹配到对应路由规则。
解决方法
方法1:自定义路径转换器(推荐)
- 在你的App目录下新建
converters.py文件,写入自定义转换器:
class FullUrlConverter: # 正则里加入你需要支持的特殊字符,这里添加了/和. regex = r'[-a-zA-Z0-9_/.]+' def to_python(self, value): # 路由匹配到后转换为Python变量,直接返回原值即可 return value def to_url(self, value): # 反向生成URL时转换为路径字符串,直接返回原值即可 return value
- 在App的
urls.py中注册该转换器,修改路由配置:
from django.urls import path, register_converter from . import converters, views # 注册自定义转换器,命名为fullurl register_converter(converters.FullUrlConverter, 'fullurl') urlpatterns = [ # 替换原有的slug转换器为自定义的fullurl path("<fullurl:url>/", ProductDetailView.as_view(), name="product_detail"), ]
方法2:直接使用正则路由
如果你不想自定义转换器,也可以直接用re_path手动写匹配规则:
from django.urls import re_path urlpatterns = [ re_path(r'(?P<url>[-a-zA-Z0-9_/.]+)/$', ProductDetailView.as_view(), name="product_detail"), ]
额外注意事项
你当前存储的url字段值开头带有/,反向生成URL时会出现多余斜杠的问题(比如最终生成路径为product//xxx/xxx.html/),建议你提前将存储的url值开头的/去掉,或者在反向传参时处理:
return reverse("product:product_detail", kwargs={"url": prod.url.lstrip('/')})
内容的提问来源于stack exchange,提问作者user9745220
相关产品推荐
相关产品推荐

