Commit 9d2580dc by Marlon Bailey

added support for multiple @action and @link decorators on a viewset, along with…

added support for multiple @action and @link decorators on a viewset, along with a router testcase illustrating the failure against the master code base
parent fd4a66cf
...@@ -127,18 +127,18 @@ class SimpleRouter(BaseRouter): ...@@ -127,18 +127,18 @@ class SimpleRouter(BaseRouter):
""" """
# Determine any `@action` or `@link` decorated methods on the viewset # Determine any `@action` or `@link` decorated methods on the viewset
dynamic_routes = {} dynamic_routes = []
for methodname in dir(viewset): for methodname in dir(viewset):
attr = getattr(viewset, methodname) attr = getattr(viewset, methodname)
httpmethod = getattr(attr, 'bind_to_method', None) httpmethod = getattr(attr, 'bind_to_method', None)
if httpmethod: if httpmethod:
dynamic_routes[httpmethod] = methodname dynamic_routes.append((httpmethod, methodname))
ret = [] ret = []
for route in self.routes: for route in self.routes:
if route.mapping == {'{httpmethod}': '{methodname}'}: if route.mapping == {'{httpmethod}': '{methodname}'}:
# Dynamic routes (@link or @action decorator) # Dynamic routes (@link or @action decorator)
for httpmethod, methodname in dynamic_routes.items(): for httpmethod, methodname in dynamic_routes:
initkwargs = route.initkwargs.copy() initkwargs = route.initkwargs.copy()
initkwargs.update(getattr(viewset, methodname).kwargs) initkwargs.update(getattr(viewset, methodname).kwargs)
ret.append(Route( ret.append(Route(
......
from __future__ import unicode_literals
from django.test import TestCase
from django.test.client import RequestFactory
from rest_framework import status
from rest_framework.response import Response
from rest_framework import viewsets
from rest_framework.decorators import link, action
from rest_framework.routers import SimpleRouter
import copy
factory = RequestFactory()
class BasicViewSet(viewsets.ViewSet):
def list(self, request, *args, **kwargs):
return Response({'method': 'list'})
@action()
def action1(self, request, *args, **kwargs):
return Response({'method': 'action1'})
@action()
def action2(self, request, *args, **kwargs):
return Response({'method': 'action2'})
@link()
def link1(self, request, *args, **kwargs):
return Response({'method': 'link1'})
@link()
def link2(self, request, *args, **kwargs):
return Response({'method': 'link2'})
class TestSimpleRouter(TestCase):
def setUp(self):
self.router = SimpleRouter()
def test_link_and_action_decorator(self):
routes = self.router.get_routes(BasicViewSet)
# Should be 2 by default, and then four from the @action and @link combined
#self.assertEqual(len(routes), 6)
#
decorator_routes = routes[2:]
for i, method in enumerate(['action1', 'action2', 'link1', 'link2']):
self.assertEqual(decorator_routes[i].mapping.values()[0], method)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment