在应用中注册API

 物业美女_959 发布于 2023-02-07 16:52

使用django-rest-framework我正在使用 DefaultRouter

我想为几个应用程序提供API,所以我的问题是我可以用django方式执行此操作并将我的路由器注册放在每个应用程序URLconf中,并将它们显示为一个聚合API或理想情况下以命名空间方式显示.

换句话说,如果app1包含modelAmodelB,则app2包含modelC:

    我可以声明出现在mysite/app1/api和的两个路由器mysite/app2/api,或者

    我可以在一个api中mysite/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调用包括所有应用程序注册以及项目注册.

UPDATE

使用Nicolas Cortot的变体option 2我得到了我的特定资源API,但它没有被列为root APIat 的可用资源myserver\api\

我假设以某种方式DefaultRouter创建它自己的页面定义并向其router.register添加条目.我当前的设置(我认为Nicholas的选项1)也创建了两个独立的路由器,只有一个可以显示为服务器根目录,下面的设置myserver\api\列出users但不是片段.

这是我目前的设置:

project 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正在服务第一条匹配路线.

除非有人能告诉我,否则我似乎需要传递一个路由器变量并以某种方式添加.

3 个回答
  • 两种选择都是可能的.您可以公开routerurls在每个应用程序中,并将它们合并到您的全局urls.我通常更喜欢使用urls(选项2),因为它在每个应用程序中提供了更大的灵活性:您可以根据需要定义额外的非api URL.

    选项1

    在你的全球urls.py中:

    from app1.api.routers import router1
    from app2.api.routers import router2
    
    urlpatterns = patterns('',
        url(r'^snippets/', include('snippets.urls', namespace="snippets"))
        ...
        url(r'^app1/api/', include(router1.urls)),
        url(r'^app2/api/', include(router2.urls)),
    )
    

    您可以轻松地为两个路由器使用相同的端点(只要您注意不要使用冲突的路由):

    urlpatterns = patterns('',
        url(r'^snippets/', include('snippets.urls', namespace="snippets"))
        ...
        url(r'^api/', include(router1.urls)),
        url(r'^api/', include(router2.urls)),
    )
    

    选项2

    appN/api/urls.py中:

    router = DefaultRouter()
    router.register(r'users', views.UserViewSet)
    router.register(include('app1.apis')
    
    urlpatterns = patterns('',
        url(r'^', include(router.urls)),
        url(r'^misc/', some_other_view),
    )
    

    在你的全球urls.py中:

    urlpatterns = patterns('',
        url(r'^snippets/', include('snippets.urls', namespace="snippets"))
        ...
        url(r'^api/', include('app1.api.urls')),
        url(r'^api/', include('app2.api.urls')),
    )
    

    请注意,urls模块不需要与urls标准视图相同.

    2023-02-07 16:54 回答
  • 通过绕过单个路由器实例,如下是可能的。

    router.py在您的main项目文件夹中创建一个名为或类似文件:

    from rest_framework import routers
    common_router = routers.DefaultRouter()
    

    在每个应用程序的位置urls.py

    from main.router import common_router as router
    router.register(r'myapp-model-name', MyAppViewSet) 
    

    在您的内容中main urls.py

    import my_app1.urls  # to register urls with router
    import my_app2.urls  # to register urls with router
    ...
    # finally import router that includes all routes
    from main.router import common_router
    
    urlpatterns = [
        ...
        url(r'^api/', include(common_router.urls)),
        ...
    ]
    

    2023-02-07 16:54 回答
  • 要在同一个API根目录中获取所有应用程序,您需要使用相同的DefaultRouter注册所有应用程序.

    实现此目的的一种方法是创建一个自定义路由器,它拦截寄存器调用并将其传播到共享路由器.然后,您可以使用此共享路由器来获取API.

    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())),   
    )   
    

    如果您不想显式导入网址,可以按惯例执行:

    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
    

    2023-02-07 16:54 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有