在 Django 中,如何将模块的 url 配置封装在模块内?

In Django, how do you keep a module's url configurations encapsulated inside the module?

目前,我将 url 配置导入我的 Django 项目:

from django.conf.urls import include
from django.contrib import admin
from django.urls import path, re_path
from rest_framework import routers
from greeter.views import GreeterViewSet

ROUTER = routers.DefaultRouter()
ROUTER.register(r'greeters', GreeterViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^', include(ROUTER.urls)),
]

有什么方法可以移动代码的这些部分:

ROUTER = routers.DefaultRouter()
ROUTER.register(r'greeters', GreeterViewSet)

greeter/urls.py 中的单独文件?

并且仍然保留这些 URL:

我试过:

my_project/urls.py

from django.conf.urls import include
from django.contrib import admin
from django.urls import path, re_path

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^greeters/', include('greeter.urls')),
]

greeter/urls.py

from django.conf.urls import url, include
from rest_framework import routers
from .views import GreeterViewSet

ROUTER = routers.DefaultRouter()
ROUTER.register(r'^', GreeterViewSet)

urlpatterns = [
    url(r'^', include(ROUTER.urls)),
]

但是得到了:

$ curl -H 'Accept: application/vnd.api+json; indent=2' -X POST http://localhost:8000/greeters/
{
  "errors": [
    {
      "detail": "Method \"POST\" not allowed.",
      "source": {
        "pointer": "/data"
      },
      "status": "405"
    }
  ]
}

如果有帮助,这是我的原始问题,已解决:

更新:

在答案的帮助下,我得出了这个解决方案:

my_project/urls.py

from django.conf.urls import include
from django.contrib import admin
from django.urls import re_path

urlpatterns = [
    re_path('admin/', admin.site.urls),
    re_path('greeters/', include('greeter.urls')),
]

greeter/urls.py

from django.conf.urls import include
from django.urls import re_path
from rest_framework import routers
from .views import GreeterViewSet

ROUTER = routers.DefaultRouter()
ROUTER.register(r'', GreeterViewSet)

urlpatterns = [
    re_path(r'', include(ROUTER.urls)),
]

有了这个:

我认为这是我能得到的最好的了。再次感谢所有帮助:)

从正则表达式中删除 ^Caret 符号)即可完成工作

# greeter/urls.py
# your code

urlpatterns = [
    url(r'', include(ROUTER.urls)),
]

我之前跟你说过,路由器需要一个前缀。您需要从主 URL 中删除该前缀并在路由器本身中使用它。

主要内容:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('greeter.urls')),
]

应用程序:

ROUTER = routers.DefaultRouter()
ROUTER.register(r'^greeter/', GreeterViewSet)

urlpatterns = ROUTER.urls

(因为除了路由器的 URL 之外没有任何 URL,所以不需要在那里使用 include,直接使用路由器 URL 即可。)

另请注意,这整件事几乎肯定不是您想做的;这意味着除了您的视图集之外,您永远不能拥有任何 URL。