Multiples @detail_route with the same url_path

This commit allows you to have multiple class method in your ViewSet
each one with the same 'url_path' but different HTTP method, e.g.:

     class MyViewSet(viewsets.GenericViewset):

         @detail_route(methods=['get'], url_path='cancel')
	 def cancel_get(self, *args, **kwargs):
             pass

     	 @detail_route(methods=['post'], url_path='cancel')
     	 def cancel_post(self, *args, **kwargs):
             pass
This commit is contained in:
Manuel Kaufmann 2016-07-14 18:03:47 -05:00
parent 91aad9299b
commit a6aebb66b9

View File

@ -238,7 +238,7 @@ class SimpleRouter(BaseRouter):
"""
Use the registered viewsets to generate a list of URL patterns.
"""
ret = []
urls_data = {}
for prefix, viewset, basename in self.registry:
lookup = self.get_lookup_regex(viewset)
@ -260,7 +260,31 @@ class SimpleRouter(BaseRouter):
view = viewset.as_view(mapping, **route.initkwargs)
name = route.name.format(basename=basename)
ret.append(url(regex, view, name=name))
# It is possible to define multiples '@detail_route' for the
# same endpoint with different methods (GET, POST, etc). So, we
# need to merge all those routes with the same URL allowing
# those multiples method
if regex in urls_data:
# merge mapping and view for the same regex
urls_data[regex]['mapping'].update(mapping)
else:
urls_data[regex] = {
'mapping': mapping,
'viewset': viewset,
'route': route,
'name': name,
}
ret = []
# Build all the URLs for the values saved on the previous iteration
for regex, values in urls_data.items():
name = values['name']
view = values['viewset'].as_view(
values['mapping'],
**values['route'].initkwargs
)
ret.append(url(regex, view, name=name))
return ret