匹配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 没有 api
、internal
或 admin
前缀,此配置的要点是呈现 MainView
:
/api/users/...
— 找到
/api/foo/
— 未找到
/foo/
— 找到
我怎样才能让它更简单、更能揭示意图?
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())
]
我目前正在使用以下 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 没有 api
、internal
或 admin
前缀,此配置的要点是呈现 MainView
:
/api/users/...
— 找到/api/foo/
— 未找到/foo/
— 找到
我怎样才能让它更简单、更能揭示意图?
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())
]