Django中URL反向解析报错NoReverseMatch:无法匹配'favourite'路由
Django中URL反向解析报错NoReverseMatch:无法匹配'favourite'路由
这个错误的核心原因很明确:你在模板中调用反向路由解析时,传递的album.id没有获取到有效值,变成了空字符串,导致无法匹配要求必须传入整数类型album_id的favourite路由(路由定义是music/<int:album_id>/favourite/,必须要有一个整数参数)。
我帮你梳理下具体问题和解决办法:
1. 直接触发错误的问题点
看你的视图代码,不管是favourite视图还是渲染details.html的视图,传递给模板的上下文变量是复数的albums(其实它是单个Album对象,因为get_object_or_404返回的是单个实例),但你在模板第11行的form action里用的是单数的album.id——这个album变量在模板的上下文里根本不存在,所以解析出来的参数是空字符串,直接导致反向路由失败。
2. 快速修复方案
把模板里的这行代码:
<form action ="{% url 'userapp:favourite' album.id %}" method="post">
改成:
<form action ="{% url 'userapp:favourite' albums.id %}" method="post">
也就是把album.id换成albums.id,和视图传递的上下文变量名保持一致。
3. 更合理的代码优化建议
不过这里有个变量名语义混淆的问题:你用复数的albums来存储单个Album对象,很容易自己搞混。建议统一修改成单数的变量名,让代码更清晰:
修改views.py中的变量名
def favourite(request, album_id): # 把变量名从albums改成album,符合单个实例的语义 album = get_object_or_404(Album, pk=album_id) try: selected_song = album.song_set.get(pk=request.POST['song']) except (KeyError, Song.DoesNotExist): return render(request, 'userapp/details.html', { 'album': album, # 同步改成单数 'error_message': "You did not select a valid song", }) else: selected_song.is_favourite = True selected_song.save() return render(request, 'userapp/details.html', {'album': album}) # 同步改成单数
然后修改details.html中的对应代码
# form action改成单数的album.id <form action ="{% url 'userapp:favourite' album.id %}" method="post"> # 其他用到该对象的地方也同步修改,比如歌曲循环部分 {% for song in album.song_set.all %}
这样变量名语义一致,后续维护也不容易再犯类似的错误。
4. 额外检查点
如果修改后还是有问题,建议确认:
- 渲染
details.html的主视图(你没贴出来的那个),传递给模板的上下文变量是不是也是album(或者albums,保持和修改后的一致) - 确保当前页面确实是在展示单个专辑的详情,也就是上下文里的
album/albums对象是存在且有效的,id属性不为空
备注:内容来源于stack exchange,提问作者Pondo
相关产品推荐
相关产品推荐

