【问题标题】:Django url config with multiple urls matching具有多个匹配的 url 的 Django url 配置
【发布时间】:2017-02-22 17:41:59
【问题描述】:

在我们的一个 Django 应用程序中,我们为视图定义了多个 url。

第一个 URL 将一个通用特征与 pk 和第二个匹配组匹配。 第二个 URL 匹配一个带有 pk 的子特征。

在这两个 url 之间定义了更多的 url,因此一次查看它们并不容易。或者,例如,子功能将有自己的 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),

现在由于 url 未正确匹配,子功能中断,'subfeature' 在第一个 url 中匹配为 pk

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

【问题讨论】:

  • 如果改变正则表达式的顺序会怎样?

标签: python django


【解决方案1】:

Django 的 URL 按照它们在 urls.py 文件中定义的顺序进行匹配。您面临的问题是因为您的正则表达式模式匹配 subfeature 作为 url 的一部分并调用不正确的视图。

与其使正则表达式的逻辑复杂化,我建议您将其简化,因为正则表达式匹配是一项繁重的计算任务,尤其是当您处理每秒数百万个请求的 API 时。

只需更改您定义 URL 的顺序即可。例如,顺序应该是这样的:

 /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。

【讨论】:

    【解决方案2】:

    我的建议是您应该将类​​似的命名原则应用为 RESTful 接口,因此切勿将原始 PK 单独作为 URL 公开。

    相反,您应该始终提供某种命名空间,以明确您的 URL 所引用的内容。例如:

    # new urls.py
    url(r'^feature/(?P<pk>[^/]+)/', views.b),
    url(r'^subfeature/', views.a),
    

    这不仅可以解决您的问题,还可以防止多个表 PK 之间的潜在混淆,并使其在未来更容易扩展。顺便说一句,它也符合django docs

    只要您也可以控制 GUI,这应该是一个简单的更改。但是,如果您现有的网址必须保留,则其他答案更合适。

    【讨论】:

      【解决方案3】:

      对此没有一般的答案。任何使 url 更通用的更改都可能会破坏它后面的其他 url。

      在这种情况下,您可以交换 url,以便 subfeature/ 将匹配子功能 url,而任何其他 url 将通过并匹配 views.b

      url(r'^subfeature/', views.a),
      url(r'^(?P<pk>[^/]+)/', views.b),
      

      【讨论】:

        【解决方案4】:

        作为一般规则,您需要在定义 urlpatterns 时考虑顺序。

        问题是 django 会尝试通过尝试将 url 匹配到每个模式中来找到匹配项,并且会在找到第一个匹配的 url 时尝试访问视图。

        url(r'^(?P<pk>[^/]+)/', views.b),
        url(r'^subfeature/', views.a),
        

        在这里,它将首先将 url 与最初存在变量的第一个模式匹配,并尝试将“subfeature”作为 pk 并告诉您它找不到任何 id="subfeature" 的对象(一个模式尝试)

        所以是的,请使用用户 knbk 的解决方案。颠倒顺序并记住这一点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-07
          • 2014-01-18
          • 2012-08-29
          相关资源
          最近更新 更多