匹配Django中没有前缀的所有URL

时间:2016-01-11 17:16:11

标签: python django django-urls

我目前正在使用以下urls.py

api_patterns = [
    url(r'^users/', include('users.urls', namespace='user')),
]

internal_patterns = [
    # ...
]

urlpatterns = [
    url(r'^api/', include(api_patterns)),
    url(r'^internal/', include(internal_patterns)),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^(?!(?:api|internal|admin)/)', MainView.as_view()),
]

此配置的目的是在网址没有MainViewapiinternal前缀的情况下呈现admin

  • /api/users/... - 找到了
  • /api/foo/ - 未找到
  • /foo/ - 找到了

我怎样才能让它变得更简单,更有意思?

2 个答案:

答案 0 :(得分:2)

如果您在两个网址中执行此操作,我认为您的意图会更明确:

url(r'^(api|internal|admin)/', SomeView.as_view()),
url(r'^.*', MainView.as_view())
仅当网址不以api,internal或admin开头时才会执行

MainView

如果网址以api / internal / admin开头但与上面的模式不匹配,则会执行{p> SomeView。您可以自定义此视图以返回默认的404页面,或根据需要执行其他功能。

使用您的示例:

  • /api/users将执行include(api_patterns)
  • /api/foo将执行SomeView
  • /foo将执行MainView

修改

要解决注释中的第一点:url模式是正则表达式,而您可以将这些模式提取到变量中以删除重复,这会使代码难以阅读。这是删除重复的一个例子(我相信你可以提出其他的):

d = OrderedDict([
    (r'api', api_patterns),
    (r'internal', internal_patterns),
    (r'admin', admin.site.urls),
])

main_view_re = r'^!({})/'.format('|'.join(d.keys()))

urlpatterns = [url(r'^{}/'.format(k), include(v)) for k, v in d]
urlpatterns.append(url(main_view_re, MainView.as_view()))

答案 1 :(得分:-2)

urlpatterns = [
    url(r'^api/', include(api_patterns)),
    url(r'^internal/', include(internal_patterns)),
    url(r'^admin/', include(admin.site.urls)),
    url(r'', MainView.as_view()),
]

不留任何前缀将允许您捕获用户在URL conf与api,internal和admin url匹配后可能尝试的任何URL。