Django 2.1.4出现NoReverseMatch错误:无法匹配'mesChambres'路由
错误原因分析
从你给出的错误信息和代码来看,主要是两个核心问题导致了这个反向解析失败:
redirect函数参数传递方式错误
你在DepotAnnView的post方法里写了:
return redirect('mesChambres', args=[id,nbChambre])
这里的问题在于,redirect函数接收位置参数时,要么直接把参数跟在视图名后面,要么用args传递位置参数的元组(注意是作为位置参数传递,不是关键字参数)。你当前的写法会把args当成一个关键字参数传给reverse函数,导致Django试图寻找需要args这个关键字参数的路由,但你的路由定义的是idAnn和nbCh两个位置参数,自然匹配失败。
- 路由参数未指定类型(可选但推荐)
你的urls.py里的路由:
path('depotAnnonce/mesChambres/<idAnn>/<nbCh>', views.MesChambreView.as_view(), name ='mesChambres'),
没有指定参数类型(比如<int:idAnn>),虽然Django默认会把参数当作字符串处理,但明确指定类型可以避免潜在的类型转换问题,也让路由规则更清晰。
另外,你的MesChambreView还有两个潜在的bug:
post方法里用request.args是错误的,Django中没有这个属性,URL里的位置参数在类视图中应该通过self.kwargs或方法参数获取;post方法的签名没有包含idAnn和nbCh,导致你无法在post逻辑中拿到这两个关键参数。
解决方法
1. 修正redirect的参数传递方式
把redirect的调用改成以下两种正确方式之一:
方式一:直接传递位置参数
return redirect('mesChambres', id, nbChambre)
方式二:用args传递位置参数元组
return redirect('mesChambres', args=(id, nbChambre))
2. 优化路由定义(指定参数类型)
修改urls.py中的路由,为参数指定整数类型(因为你的ID和房间数都是整数):
path('depotAnnonce/mesChambres/<int:idAnn>/<int:nbCh>', views.MesChambreView.as_view(), name='mesChambres'),
3. 修复MesChambreView的post方法
因为post逻辑需要用到URL中的idAnn和nbCh参数,所以要修改方法签名,并且正确获取这些参数:
class MesChambreView(TemplateView): template_name = "base/mesChambres.html" def get(self, request, idAnn, nbCh): form = Chambreform() # 把参数传给模板,方便后续使用 return render(request, self.template_name, {'form': form, 'idAnn': idAnn, 'nbCh': nbCh}) def post(self, request, idAnn, nbCh): form = Chambreform(request.POST) if form.is_valid(): loyerCh = form.cleaned_data['loyerCh'] superficieCh = form.cleaned_data['superficieCh'] # 直接使用方法参数中的idAnn ch = Chambre(Chambre.objects.count()+1, idAnn, loyerCh, superficieCh) ch.save() return redirect('index') # 验证失败时返回模板并保留参数 return render(request, self.template_name, {'form': form, 'idAnn': idAnn, 'nbCh': nbCh})
注意:之前的request.args是错误用法,直接删除即可。
4. 额外建议:避免手动生成ID
你当前用Annonce.objects.count()+1和Chambre.objects.count()+1生成ID,这种方式在并发场景下会导致ID冲突。建议让Django自动生成主键(默认的AutoField就可以),不需要手动指定:
# 示例Annonce模型定义(省略自动生成的id字段) class Annonce(models.Model): titre = models.CharField(max_length=255) nbChambre = models.IntegerField() # 其他字段... user = models.ForeignKey(User, on_delete=models.CASCADE) # 保存时无需传id ann = Annonce(titre=titre, nbChambre=nbChambre, ..., user=request.user) ann.save() # 之后可以通过ann.id获取自动生成的ID
按照以上步骤修改后,你的反向解析应该就能正常工作,mesChambres视图的post逻辑也能正确获取并使用URL参数了。
内容的提问来源于stack exchange,提问作者L.Soulignac

