Django抛出'set' object is not reversible错误排查修复
问题原因
这个异常和模板代码、手动使用set类型没有任何关系,核心是URL配置的写法不符合Django要求。
Django执行{% url %}反向解析时,会按顺序遍历urlpatterns里的所有路由匹配别名,这个遍历逻辑要求urlpatterns必须是有序可索引的列表(list)类型。如果你在任意一个urls.py(不管是根路由还是应用路由)里,误把包裹路由条目的方括号[]写成了花括号{},Python会自动把这组路由解析为无序的集合(set)类型,集合不支持按顺序索引遍历,就会抛出'set' object is not reversible错误。
错误提示指向模板里的
{% url 'home' %}只是因为模板渲染到这一行时才第一次触发反向解析逻辑,真正的bug点在路由配置文件里,和模板标签写法无关,和你错误栈里显示的“反向遍历url_patterns时报错”的特征完全吻合。
修复方法
- 逐个检查项目下所有
urls.py文件(包含根路由、所有注册到路由表的应用路由)里的urlpatterns定义:- 错误写法(触发本次异常的写法):用花括号包裹路由条目,Python会自动识别为set类型
urlpatterns = { path('', views.index, name='home'), path('login/', views.login, name='login'), # 其他路由条目 }- 正确写法:必须用方括号包裹路由条目,解析为Django要求的list类型
urlpatterns = [ path('', views.index, name='home'), path('login/', views.login, name='login'), # 其他路由条目 ] - 额外排查所有用到
include()的路由位置,不要给include()传入花括号包裹的路由集合,所有路由组的包裹符号统一用方括号。 - 修改保存后重启Django开发服务,重新访问首页即可正常加载,反向解析逻辑会恢复正常。
补充说明
不需要你手动调用set()才会生成set类型,Python原生语法中,花括号包裹逗号分隔的多个值、且不是键值对格式时,就会自动解析为set类型,这个属于非常常见的笔误,大多是敲代码时手滑把方括号敲成花括号、复制粘贴路由时漏改符号导致的。
内容的提问来源于stack exchange,提问作者sooronson
相关产品推荐
相关产品推荐

