使用 django-rest-framework 我正在使用 DefaultRouter
我想为多个应用程序提供 API,所以我的问题是我能否以 django 方式执行此操作并将我的路由器注册放在每个应用程序 URLconf 中,并让它们显示为一个聚合 api 或理想情况下以命名空间方式显示。
换句话说,如果 app1
包含 modelA
和 modelB
, 而 app2
包含 modelC
:
mysite/app1/api
处的 2 个路由器吗?和 mysite/app2/api
, 或 mysite/api
上有一个 api 吗?它列出了所有三个模型,但在他们自己的应用程序中注册了各个模型 urls.py
类似的东西
router = DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(include('app1.apis')
router.register(include('app2.apis')
或者,是否有一种简单的方法可以让我的路由器变量在每个应用程序的 URLconf 中可用,以便他们可以调用
router.register
?我不确定是否urlpatterns = patterns('',
url(r'^snippets/', include('snippets.urls', namespace="snippets"))
...
url(r'^api/', include(router.urls)),
实际上导致
app1/urls.py
中的代码在那一点执行,以便它可以调用 router.register
以某种方式,以便最终 url 调用包括所有应用程序注册以及项目注册。更新
使用 Nicolas Cortot 的变体
option 2
我得到我的特定资源 API
工作,但它未在 root API
中列为可用资源在 myserver\api\
我认为不知何故
DefaultRouter
创建它自己的页面定义和 router.register
添加条目。我当前的设置(我认为 Nicholas 的选项 1 也是如此)创建了两个单独的路由器,只有一个可以显示为服务器根目录,设置如下,myserver\api\
列表 users
但不是片段。这是我目前的设置:
项目 urls.py:
router = DefaultRouter()
router.register(r'users', views.UserViewSet)
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^api/', include(router.urls)),
url(r'^api/', include('snippets.apiurls')),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
)
项目/片段/apiurls.py:
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)
urlpatterns = patterns('',
url(r'^', include(router.urls)),
)
如果我颠倒项目中条目的顺序
urls.py
如: url(r'^api/', include('snippets.apiurls')),
url(r'^api/', include(router.urls)),
然后我得到
snippets
列出但未列出 users
我猜 Django 正在服务第一个匹配的路由。
除非有人能告诉我,否则我似乎需要一个单一的路由器变量来传递并以某种方式添加。
最佳答案
要在同一个 API 根中获取所有应用程序,您需要使用相同的 DefaultRouter 注册所有应用程序。
实现这一点的一种方法是制作一个自定义路由器,它拦截注册调用并将其传播到共享路由器。然后您使用此共享路由器来获取 api url。
class SharedAPIRootRouter(SimpleRouter):
shared_router = DefaultRouter()
def register(self, *args, **kwargs):
self.shared_router.register(*args, **kwargs)
super().register(*args, **kwargs)
# if not py3: super(SharedAPIRootRouter, self).register(*args,**kwargs)
然后在每个应用程序中:
# in app1/urls.py
router = SharedAPIRootRouter()
router.register(r'app1', App1ModelViewSet)
# in app2/urls.py
router = SharedAPIRootRouter()
router.register(r'app2', App2ModelViewSet)
在您的主 urls.py 中,您必须确保导入应用程序 url,以便在我们要求 shared_router.urls 之前进行注册
import app1.urls
import app2.urls
def api_urls():
return SharedAPIRootRouter.shared_router.urls
urlpatterns = patterns(
'',
url(r'^api/', include(api_urls())),
)
如果您不想显式导入 url,则可以按惯例进行:
def api_urls():
from importlib import import_module
for app in settings.INSTALLED_APPS:
try:
import_module(app + '.urls')
except (ImportError, AttributeError):
pass
return SharedAPIRootRouter.shared_router.urls
关于django - 在应用程序中注册 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20825029/