Django path路由普通字符串与r原始字符串写法有何区别
两种Django路由写法的核心差异
这两种写法的差异本质和r前缀没太大关系,核心是新旧路由API的规则混淆,甚至第二种写法本身就是对path()函数的误用,具体拆解:
1. r原始字符串前缀没有特殊魔法
Python中字符串前加r代表声明原始字符串,唯一作用是关闭字符串内部的反斜杠转义逻辑:普通字符串里\n会被解析成换行符,原始字符串里\n就是反斜杠加字母n两个普通字符。
在你举的例子里,路由路径是index/,本身没有任何需要转义的反斜杠字符,所以'index/'和r'index/'是完全一模一样的字符串,传给Django之后框架的处理逻辑没有任何区别。
大家写正则类路由时习惯加r,只是因为正则表达式经常用到\d、\w这类带反斜杠的语法,用原始字符串不用重复写双反斜杠转义,写起来更省事,不是什么框架要求的特殊写法。
2. 真正的问题:^和$是正则路由专属语法,path()根本不认
第二种写法里的^(匹配字符串开头)、$(匹配字符串结尾)是正则表达式的锚点符号,只有走正则匹配逻辑的路由函数(Django 1.x版本的url()、Django 2.0+版本的re_path())才会识别这两个符号。
如果你把r'^index/$'作为路由参数传给path(),这个路由基本就废了:
path()从设计上就不用正则做匹配,它走的是路径段精确匹配规则,会把^和$当成URL里的普通字符,只会去匹配路径为/^index/$的请求,正常用户访问/index/根本碰不到这个路由。- 你日常用的
path('index/', views.xxx)才是path()的正确写法,path()默认就会做全路径精确匹配,不需要额外加^、$做锚定,写index/就只会精准匹配/index/的请求,不会误匹配其他带多余前缀、后缀的路径。
3. 为什么很多参考案例会写带r和^$的形式?
你看到的这类案例基本逃不出两种情况:
- 是Django 1.x时代的遗留内容:Django 2.0之前根本没有
path()函数,所有路由都靠正则匹配的url()实现,必须加^和$才能保证匹配不越界,加r也是写正则的常规习惯; - 是示例作者自己没搞清楚
path()和re_path()的区别,把正则路由的写法直接生搬硬套到path()上,属于错误示例,不用照着学。
补充说明:如果把带
^$的原始字符串传给re_path(),也就是re_path(r'^index/$', views.xxx),那它和path('index/', views.xxx)的匹配效果是完全一致的,只是前者靠正则实现,后者用更简洁的路径段规则实现而已。
内容的提问来源于stack exchange,提问作者ReliableAirRepair
相关产品推荐
相关产品推荐

