在我们的一个Django应用程序中,我们为视图定义了多个URL。
第一个网址与pk和第二个匹配组的常规功能相匹配。 第二个URL匹配带有pk的子功能。
在这两个网址之间定义了更多网址,因此不容易一次看到它们。或者,例如,子功能将有自己的url.py。
# old urls.py
url(r'^(?P<pk>\d+)/', views.b),
url(r'^subfeature/', views.a),
一段时间后,pk中也允许使用字母,因此我们现在必须将 \ d + 更改为 [^ /] + 。
# new urls.py
url(r'^(?P<pk>[^/]+)/', views.b),
url(r'^subfeature/', views.a),
现在子功能因为网址未正确匹配而中断,“子功能”在第一个网址中匹配为 pk 。
如何在更改网址正则表达式时避免破坏其他网址?
答案 0 :(得分:9)
对此没有一般性的答案。任何使网址更通用的更改都可能会破坏其后的其他网址。
在这种情况下,您可以更换网址,以便subfeature/
与子网址匹配,其他任何网址都将落实并匹配views.b
:
url(r'^subfeature/', views.a),
url(r'^(?P<pk>[^/]+)/', views.b),
答案 1 :(得分:5)
我的建议是,您应该将类似的命名原则应用为RESTful接口,因此不要将原始PK单独作为URL公开。
相反,您应该始终提供某种命名空间,以明确您的URL引用的内容。例如:
# new urls.py
url(r'^feature/(?P<pk>[^/]+)/', views.b),
url(r'^subfeature/', views.a),
这不仅可以解决您的问题,还可以防止多个表PK之间的混淆,并使将来更容易扩展。顺便提一下,它也符合django docs。
只要您也可以控制GUI,这应该是一个简单的改变。但是,如果您的现有网址必须,则其他答案更合适。
答案 2 :(得分:1)
作为一般规则,您需要在定义urlpatterns时考虑顺序。
事情是django将尝试通过尝试将url放入每个模式来尝试找到匹配,并且只要找到第一个url匹配就会尝试访问视图。
url(r'^(?P<pk>[^/]+)/', views.b),
url(r'^subfeature/', views.a),
这里,它首先将url与第一个模式匹配,其中最初有一个变量,并尝试将“subfeature”作为pk,并告诉你它找不到id =“subfeature”的任何对象(一个模式试过)
所以是的,请使用用户knbk的解决方案。扭转秩序并牢记这一点。
答案 3 :(得分:0)
Django的URL按照urls.py
文件中定义的顺序进行匹配。您面临的问题是因为您的正则表达式模式与subfeature
匹配作为网址的一部分并调用不正确的视图。
我建议你不要使正则表达式的逻辑复杂化,因为正则表达式匹配是繁重的计算任务,尤其是在处理速率为每秒数百万次请求的API时。
只需更改您定义网址的顺序即可。例如,顺序应该是:
/my-object/
/my-object/category/
/my-object/category/(?P<pk>[^/]+)/
/my-object/(?P<pk>[^/]+)/
因此,在您的情况下,URL声明的顺序应颠倒为:
url(r'^subfeature/', views.a),
url(r'^(?P<pk>[^/]+)/', views.b),
现在,首先"subfeature"
将作为整个文本进行匹配。如果不匹配,请求将转到下一个URL,即您的正则表达式模式。