From 2cbe3c61beef30158b86210ec72ba0e5eb6dff9c Mon Sep 17 00:00:00 2001 From: David Graves Date: Wed, 30 Mar 2022 23:31:10 -0500 Subject: [PATCH] raise ImproperlyConfigured if basename already exists --- rest_framework/routers.py | 17 ++++++++++++++++- tests/test_routers.py | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/rest_framework/routers.py b/rest_framework/routers.py index e0ae24b95..3a0eb87e7 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -52,12 +52,27 @@ class BaseRouter: def register(self, prefix, viewset, basename=None): if basename is None: basename = self.get_default_basename(viewset) - self.registry.append((prefix, viewset, basename)) + + if not self.basename_already_registered(basename): + self.registry.append((prefix, viewset, basename)) # invalidate the urls cache if hasattr(self, '_urls'): del self._urls + def basename_already_registered(self, new_basename): + """ + If `basename` is already registered, raise an exception + """ + for route in self.registry: + prefix, viewset, basename = route + if new_basename == basename: + msg = (f'Route with basename "{new_basename}" is already registered. ' + f'Please provide a unique basename for viewset "{viewset}"') + raise ImproperlyConfigured(msg) + + return False + def get_default_basename(self, viewset): """ If `basename` is not specified, attempt to automatically determine diff --git a/tests/test_routers.py b/tests/test_routers.py index f767a843d..2ef2bd541 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -481,3 +481,17 @@ class TestViewInitkwargs(URLPatternsTestCase, TestCase): initkwargs = match.func.initkwargs assert initkwargs['basename'] == 'routertestmodel' + + +class TestDuplicateBasename(URLPatternsTestCase, TestCase): + def test_exception_for_duplicate_basename(self): + class NoteViewSet(viewsets.ModelViewSet): + queryset = RouterTestModel.objects.all() + + self.router = SimpleRouter(trailing_slash=False) + self.router.register(r'notes', NoteViewSet) + + with pytest.raises(ImproperlyConfigured): + self.router.register(r'notes_duplicate', NoteViewSet) + + self.router.register(r'notes_duplicate_2', NoteViewSet, basename='note_duplicate') \ No newline at end of file