Django url配置多个url匹配

时间:2016-10-13 14:23:06

标签: python django

在我们的一个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

如何在更改网址正则表达式时避免破坏其他网址?

4 个答案:

答案 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,即您的正则表达式模式。