Refactor dynamic route checking & collection

This commit is contained in:
Ryan P Kilby 2017-12-22 02:24:39 -05:00
parent 72b73790dd
commit c2476fc035

View File

@ -185,25 +185,21 @@ class SimpleRouter(BaseRouter):
# converting to list as iterables are good for one pass, known host needs to be checked again and again for # converting to list as iterables are good for one pass, known host needs to be checked again and again for
# different functions. # different functions.
known_actions = list(flatten([route.mapping.values() for route in self.routes if isinstance(route, Route)])) known_actions = list(flatten([route.mapping.values() for route in self.routes if isinstance(route, Route)]))
extra_actions = viewset.get_extra_actions()
# Determine any `@detail_route` or `@list_route` decorated methods on the viewset # checking action names against the known actions list
detail_routes = [] not_allowed = [
list_routes = [] action.__name__ for action in extra_actions
for methodname in dir(viewset): if action.__name__ in known_actions
attr = getattr(viewset, methodname) ]
httpmethods = getattr(attr, 'bind_to_methods', None) if not_allowed:
detail = getattr(attr, 'detail', True) msg = ('Cannot use the @action decorator on the following '
if httpmethods: 'methods, as they are existing routes: %s')
# checking method names against the known actions list raise ImproperlyConfigured(msg % ', '.join(not_allowed))
if methodname in known_actions:
raise ImproperlyConfigured('Cannot use @detail_route or @list_route ' # partition detail and list actions
'decorators on method "%s" ' detail_actions = [action for action in extra_actions if action.detail]
'as it is an existing route' % methodname) list_actions = [action for action in extra_actions if not action.detail]
httpmethods = [method.lower() for method in httpmethods]
if detail:
detail_routes.append((httpmethods, methodname))
else:
list_routes.append((httpmethods, methodname))
def _get_dynamic_routes(route, dynamic_routes): def _get_dynamic_routes(route, dynamic_routes):
ret = [] ret = []
@ -224,19 +220,16 @@ class SimpleRouter(BaseRouter):
return ret return ret
ret = [] routes = []
for route in self.routes: for route in self.routes:
if isinstance(route, DynamicRoute) and route.detail: if isinstance(route, DynamicRoute) and route.detail:
# Dynamic detail routes (@detail_route decorator) routes += _get_dynamic_routes(route, detail_actions)
ret += _get_dynamic_routes(route, detail_routes)
elif isinstance(route, DynamicRoute) and not route.detail: elif isinstance(route, DynamicRoute) and not route.detail:
# Dynamic list routes (@list_route decorator) routes += _get_dynamic_routes(route, list_actions)
ret += _get_dynamic_routes(route, list_routes)
else: else:
# Standard route routes.append(route)
ret.append(route)
return ret return routes
def get_method_map(self, viewset, method_map): def get_method_map(self, viewset, method_map):
""" """