{"action":"created","issue":{"url":"https://api.github.com/repos/chibisov/drf-extensions/issues/83","labels_url":"https://api.github.com/repos/chibisov/drf-extensions/issues/83/labels{/name}","comments_url":"https://api.github.com/repos/chibisov/drf-extensions/issues/83/comments","events_url":"https://api.github.com/repos/chibisov/drf-extensions/issues/83/events","html_url":"https://github.com/chibisov/drf-extensions/issues/83","id":75415315,"number":83,"title":"DefaultRouterExtensible","user":{"login":"cancan101","id":51059,"avatar_url":"https://avatars.githubusercontent.com/u/51059?v=3","gravatar_id":"","url":"https://api.github.com/users/cancan101","html_url":"https://github.com/cancan101","followers_url":"https://api.github.com/users/cancan101/followers","following_url":"https://api.github.com/users/cancan101/following{/other_user}","gists_url":"https://api.github.com/users/cancan101/gists{/gist_id}","starred_url":"https://api.github.com/users/cancan101/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cancan101/subscriptions","organizations_url":"https://api.github.com/users/cancan101/orgs","repos_url":"https://api.github.com/users/cancan101/repos","events_url":"https://api.github.com/users/cancan101/events{/privacy}","received_events_url":"https://api.github.com/users/cancan101/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/chibisov/drf-extensions/labels/Feature/enhancement","name":"Feature/enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-05-12T01:19:39Z","updated_at":"2015-12-06T15:44:21Z","closed_at":null,"body":"The issue right now is that if there are multiple applications within the same Django project, the root api view does not pull in all end points. This helps to solve that problem.\r\n\r\nWhat do you think of pulling in something like: https://github.com/tomchristie/django-rest-framework/pull/2001 to drf-extensions?\r\n\r\nThe implementation would look something like:\r\n```python\r\nclass DefaultRouterExtensible(DefaultRouter):\r\n    def __init__(self, require_authenticated=True, include_root_view=True, *args, **kwargs):\r\n        super(DefaultRouterExtensible, self).__init__(*args, **kwargs)\r\n        self.require_authenticated = require_authenticated\r\n        self.include_root_view = include_root_view\r\n\r\n    def get_api_root_dict(self):\r\n        api_root_dict = OrderedDict()\r\n        list_name = self.routes[0].name\r\n        for prefix, viewset, basename in self.registry:\r\n            api_root_dict[prefix] = list_name.format(basename=basename)\r\n        return api_root_dict\r\n\r\n    def get_api_root_view(self):\r\n        \"\"\"\r\n        Return a view to use as the API root.\r\n        \"\"\"\r\n        api_root_dict = self.get_api_root_dict()\r\n\r\n        class APIRoot(views.APIView):\r\n            permission_classes = (permissions.IsAuthenticated, ) if self.require_authenticated else ()\r\n\r\n            _ignore_model_permissions = True\r\n\r\n            def get(self, request, *args, **kwargs):\r\n                ret = OrderedDict()\r\n                namespace = get_resolver_match(request).namespace\r\n                for key, url_name in api_root_dict.items():\r\n                    if namespace:\r\n                        url_name = namespace + ':' + url_name\r\n                    try:\r\n                        ret[key] = reverse(\r\n                            url_name,\r\n                            request=request,\r\n                            format=kwargs.get('format', None)\r\n                        )\r\n                    except NoReverseMatch: # pragma: no cover\r\n                        # Don't bail out if eg. no list routes exist, only detail routes.\r\n                        continue\r\n\r\n                return Response(ret)\r\n\r\n        return APIRoot.as_view()\r\n\r\n\r\nclass DefaultRouterAddItem(DefaultRouterExtensible):\r\n    def __init__(self, *args, **kwargs):\r\n        super(DefaultRouterAddItem, self).__init__(*args, **kwargs)\r\n        self._additional_api_root_dict = {}\r\n\r\n    def add_routes_to_root(self, route_dict):\r\n        duplicate_routes = set(self._additional_api_root_dict.keys()) & set(route_dict.keys())\r\n        # Make sure we are not attempting to add a route that already exists\r\n        assert not duplicate_routes, duplicate_routes\r\n        self._additional_api_root_dict.update(route_dict)\r\n\r\n    def get_api_root_dict(self):\r\n        ret = super(DefaultRouterAddItem, self).get_api_root_dict()\r\n        for k, v in self._additional_api_root_dict.iteritems():\r\n            ret[k] = v\r\n        return ret\r\n```"},"comment":{"url":"https://api.github.com/repos/chibisov/drf-extensions/issues/comments/162324431","html_url":"https://github.com/chibisov/drf-extensions/issues/83#issuecomment-162324431","issue_url":"https://api.github.com/repos/chibisov/drf-extensions/issues/83","id":162324431,"user":{"login":"auvipy","id":6212603,"avatar_url":"https://avatars.githubusercontent.com/u/6212603?v=3","gravatar_id":"","url":"https://api.github.com/users/auvipy","html_url":"https://github.com/auvipy","followers_url":"https://api.github.com/users/auvipy/followers","following_url":"https://api.github.com/users/auvipy/following{/other_user}","gists_url":"https://api.github.com/users/auvipy/gists{/gist_id}","starred_url":"https://api.github.com/users/auvipy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/auvipy/subscriptions","organizations_url":"https://api.github.com/users/auvipy/orgs","repos_url":"https://api.github.com/users/auvipy/repos","events_url":"https://api.github.com/users/auvipy/events{/privacy}","received_events_url":"https://api.github.com/users/auvipy/received_events","type":"User","site_admin":false},"created_at":"2015-12-06T15:44:21Z","updated_at":"2015-12-06T15:44:21Z","body":"class ContainerRouter(DefaultRouter):\r\n    def register_router(self, router):\r\n        self.registry.extend(router.registry)\r\n\r\nrouter = ContainerRouter()\r\nrouter.register_router(router1)\r\nrouter.register_router(router2)\r\n\r\nurlpatterns = [\r\n    url(r'^api/', include(router.urls)),\r\n]"}}