Merge dynamic routes, add 'detail' attribute

This commit is contained in:
Ryan P Kilby 2017-12-22 01:49:31 -05:00
parent f79cd591fa
commit e090ba2dd9

View File

@ -16,6 +16,7 @@ For example, you might have a `urls.py` that looks something like this:
from __future__ import unicode_literals from __future__ import unicode_literals
import itertools import itertools
import warnings
from collections import OrderedDict, namedtuple from collections import OrderedDict, namedtuple
from django.conf.urls import url from django.conf.urls import url
@ -30,9 +31,30 @@ from rest_framework.schemas.views import SchemaView
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from rest_framework.urlpatterns import format_suffix_patterns from rest_framework.urlpatterns import format_suffix_patterns
Route = namedtuple('Route', ['url', 'mapping', 'name', 'initkwargs']) Route = namedtuple('Route', ['url', 'mapping', 'name', 'detail', 'initkwargs'])
DynamicDetailRoute = namedtuple('DynamicDetailRoute', ['url', 'name', 'initkwargs']) DynamicRoute = namedtuple('DynamicRoute', ['url', 'name', 'detail', 'initkwargs'])
DynamicListRoute = namedtuple('DynamicListRoute', ['url', 'name', 'initkwargs'])
class DynamicDetailRoute(object):
def __new__(cls, url, name, initkwargs):
warnings.warn(
"`DynamicDetailRoute` is pending deprecation and will be removed in 3.10 "
"in favor of `DynamicRoute`, which accepts a `detail` boolean. Use "
"`DynamicRoute(url, name, True, initkwargs)` instead.",
PendingDeprecationWarning, stacklevel=2
)
return DynamicRoute(url, name, True, initkwargs)
class DynamicListRoute(object):
def __new__(cls, url, name, initkwargs):
warnings.warn(
"`DynamicListRoute` is pending deprecation and will be removed in 3.10 in "
"favor of `DynamicRoute`, which accepts a `detail` boolean. Use "
"`DynamicRoute(url, name, False, initkwargs)` instead.",
PendingDeprecationWarning, stacklevel=2
)
return DynamicRoute(url, name, False, initkwargs)
def escape_curly_brackets(url_path): def escape_curly_brackets(url_path):
@ -103,14 +125,15 @@ class SimpleRouter(BaseRouter):
'post': 'create' 'post': 'create'
}, },
name='{basename}-list', name='{basename}-list',
detail=False,
initkwargs={'suffix': 'List'} initkwargs={'suffix': 'List'}
), ),
# Dynamically generated list routes. # Dynamically generated list routes. Generated using
# Generated using @list_route decorator # @action(detail=False) decorator on methods of the viewset.
# on methods of the viewset. DynamicRoute(
DynamicListRoute(
url=r'^{prefix}/{methodname}{trailing_slash}$', url=r'^{prefix}/{methodname}{trailing_slash}$',
name='{basename}-{methodnamehyphen}', name='{basename}-{methodnamehyphen}',
detail=False,
initkwargs={} initkwargs={}
), ),
# Detail route. # Detail route.
@ -123,13 +146,15 @@ class SimpleRouter(BaseRouter):
'delete': 'destroy' 'delete': 'destroy'
}, },
name='{basename}-detail', name='{basename}-detail',
detail=True,
initkwargs={'suffix': 'Instance'} initkwargs={'suffix': 'Instance'}
), ),
# Dynamically generated detail routes. # Dynamically generated detail routes. Generated using
# Generated using @detail_route decorator on methods of the viewset. # @action(detail=True) decorator on methods of the viewset.
DynamicDetailRoute( DynamicRoute(
url=r'^{prefix}/{lookup}/{methodname}{trailing_slash}$', url=r'^{prefix}/{lookup}/{methodname}{trailing_slash}$',
name='{basename}-{methodnamehyphen}', name='{basename}-{methodnamehyphen}',
detail=True,
initkwargs={} initkwargs={}
), ),
] ]
@ -193,6 +218,7 @@ class SimpleRouter(BaseRouter):
url=replace_methodname(route.url, url_path), url=replace_methodname(route.url, url_path),
mapping={httpmethod: methodname for httpmethod in httpmethods}, mapping={httpmethod: methodname for httpmethod in httpmethods},
name=replace_methodname(route.name, url_name), name=replace_methodname(route.name, url_name),
detail=route.detail,
initkwargs=initkwargs, initkwargs=initkwargs,
)) ))
@ -200,10 +226,10 @@ class SimpleRouter(BaseRouter):
ret = [] ret = []
for route in self.routes: for route in self.routes:
if isinstance(route, DynamicDetailRoute): if isinstance(route, DynamicRoute) and route.detail:
# Dynamic detail routes (@detail_route decorator) # Dynamic detail routes (@detail_route decorator)
ret += _get_dynamic_routes(route, detail_routes) ret += _get_dynamic_routes(route, detail_routes)
elif isinstance(route, DynamicListRoute): elif isinstance(route, DynamicRoute) and not route.detail:
# Dynamic list routes (@list_route decorator) # Dynamic list routes (@list_route decorator)
ret += _get_dynamic_routes(route, list_routes) ret += _get_dynamic_routes(route, list_routes)
else: else: