为什么Django URL模式会出现美元符号,触发NoReverseMatch错误
问题根源
1. URL路由配置不匹配
你收到NoReverseMatch报错的核心原因是路由命名和参数不对应:
- 你调用
reverse("entry", args=[title])时,Django会查找名为entry的路由,你的urls.py中该路由为path("entry", views.entry, name="entry"),没有定义任何参数,根本无法接收你传入的title参数,因此匹配失败。 - 你定义的带
<str:entry>参数的词条展示路由,名称是title而非entry,和你反向解析的名称完全不对应。
报错信息里的$是Django路由正则匹配的结束标识,不是系统自动加的多余符号,本质就是你选了错误的路由做反向解析。
2. 视图逻辑缩进错误
你提到的循环仅执行一次的问题,是new视图里的重复校验逻辑缩进错误导致:
你把else块和if判断对齐放在了for循环内部,只要遍历到第一个不重名的词条,就会直接触发保存跳转逻辑,根本不会检查后续的其他词条,完全达不到全局去重的目的。
修复步骤
第一步:修正urls.py配置
删除冗余的无参数entry路由,将带参数的词条路由名称改为entry,修改后代码如下:
from django.urls import path from . import views urlpatterns = [ path("", views.index, name="index"), # 修改路由名称为entry,对应你reverse调用的名称 path("wiki/<str:entry>", views.entry, name="entry"), path("new", views.new, name="new"), path("error", views.error, name="error"), # 删掉原来的无参数path("entry", views.entry, name="entry")配置 ]
第二步:修正views.py的循环逻辑
调整缩进,让else块和for循环对齐,保证遍历完全部词条没有重复时再执行保存跳转:
def new(request): if request.method == 'POST': form = Post(request.POST) if form.is_valid(): title = form.cleaned_data['title'] lower_title = title.lower() text = form.cleaned_data['textarea'] entries = util.list_entries() exist = False # 遍历所有条目检查重复 for entry in entries: if lower_title == entry.lower(): exist = True break if exist: message = messages.warning(request, "There is already a page with this name.") context = { 'message': message, "form": Search(), "post": Post() } return render(request, 'encyclopedia/new.html',context) # 无重复再执行保存跳转 else: util.save_entry(title,text) return HttpResponseRedirect(reverse("entry", args=[title])) else: return render(request, 'encyclopedia/new.html', { "form": Search(), "post": Post() })
内容的提问来源于stack exchange,提问作者Teodor Rosu
相关产品推荐
相关产品推荐

