应用urls.py中re_path语法疑问及reverse解析slug为空的报错求助
首先,我一眼就看到了问题的根源——你在bench.urls.py的第一个re_path里犯了一个关键错误:你给视图twodigit_testt1硬传递了一个正则表达式字符串作为slug参数,这直接导致模板上下文里的slug变成了正则模式,而不是数据库对象的实际slug值!
核心错误分析
看你这段代码:
re_path(r"^$", twodigit_testt1, {'slug': r"^(?P<slug>[-a-zA-Z0-9_]+)/$"}, name='tdr'),
这里的{'slug': ...}是在给视图传递固定参数,但你传的是正则字符串,不是从数据库或请求中获取的实际slug值。这就是为什么你的debug_toolbar显示'slug': '^(?P<slug>[-a-zA-Z0-9_]+)/$'的原因——模板拿到的是这个正则,而不是你期望的对象slug,自然在调用reverse时会传入空值或者不匹配的内容,触发报错。
分步解决
1. 修正应用urls.py
首先移除第一个re_path里的错误参数,修正后的bench.urls.py应该是:
urlpatterns = [ re_path(r"^$", twodigit_testt1, name='tdr'), re_path(r"(?P<slug>[-a-zA-Z0-9_]+)/$", courtdetail, name='jhp_url'), ]
你不需要在url里给列表视图传递slug参数,列表视图的职责是获取所有需要展示的对象,而不是硬编码正则。
2. 检查列表视图逻辑
确保twodigit_testt1视图正确查询数据库对象,并将它们传递给模板。比如假设你的模型是Court,视图应该类似这样:
from django.shortcuts import render from .models import Court def twodigit_testt1(request): # 获取所有需要展示的Court对象 courts = Court.objects.all() # 根据你的业务逻辑调整查询 # 将对象列表传递给模板 return render(request, 'your_list_template.html', {'courts': courts})
这样模板里遍历courts时,每个对象都有自己的slug属性,调用get_absolute_url()就能拿到正确的参数。
3. 验证命名空间(如果使用)
如果你的应用是通过include添加到项目urls里并设置了命名空间,比如项目urls.py:
from django.urls import path, include urlpatterns = [ # 假设你的应用有前缀和命名空间 path('(?P<twodigit>[a-z]{2,3})/', include('bench.urls', namespace='bench')), ]
那你需要在get_absolute_url里加上命名空间:
def get_absolute_url(self): return reverse('bench:jhp_url', kwargs={'slug': self.slug})
模板里也需要对应调整:
<!-- 使用url标签 --> {% url 'bench:jhp_url' slug=court.slug %} <!-- 或者直接用get_absolute_url --> {{ court.get_absolute_url }}
4. 为什么直接访问详情页正常?
因为直接访问详情页时,你是在url里传入了实际的slug值(比如/en/courts/my-court-slug/),courtdetail视图能正确捕获这个参数并查询对应的对象。但列表页因为之前的错误参数,传递给模板的是正则字符串,而非实际slug,所以reverse失败。
最后验证
修正后,重新运行项目,检查debug_toolbar的模板上下文,此时slug应该是对象的实际值(比如my-court-slug),而不是正则模式,这样reverse就能正确生成url了。
内容的提问来源于stack exchange,提问作者Malik A. Rumi

