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

Match all urls without the prefix in Django

我目前正在使用以下 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()),
]

如果 url 没有 apiinternaladmin 前缀,此配置的要点是呈现 MainView

我怎样才能让它更简单、更能揭示意图?

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、内部和管理员 url 之后可能尝试的任何 URL .

我想如果你分两次 url 这样做你的意图会更清楚:

url(r'^(api|internal|admin)/', SomeView.as_view()),
url(r'^.*', MainView.as_view())

MainView 仅当 url 不以 api、internal 或 admin 开头时才会执行。

SomeView 将在 url 以 api/internal/admin 开头但不匹配其上方的模式时执行。您可以将此视图自定义为 return 默认 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()))

对于 django >= 3 而使用 re_path:

from django.urls import re_path

urlpatterns = [
    re_path(r'^.*',MainView.as_view())
]