From 822b85ac36818f0d8cb4b05f47ea5532b12a8d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Diemer?= Date: Thu, 17 Jan 2019 14:07:57 +0100 Subject: [PATCH] routers: invalidate _urls cache on register (#6407) see https://github.com/encode/django-rest-framework/issues/5660 Trying to register new routes on a router after having accessed the router `urls` attribute leads to surprising results. The route is added without error to the router's `registry` but the urls are not updated, because they are cached in `_urls`. This commit invalidates the cache after each new registration. --- rest_framework/routers.py | 4 ++++ tests/test_routers.py | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/rest_framework/routers.py b/rest_framework/routers.py index de04cb674..2c24f9099 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -100,6 +100,10 @@ class BaseRouter(six.with_metaclass(RenameRouterMethods)): basename = self.get_default_basename(viewset) self.registry.append((prefix, viewset, basename)) + # invalidate the urls cache + if hasattr(self, '_urls'): + del self._urls + 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 eae3f5458..c74055347 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -158,6 +158,12 @@ class TestSimpleRouter(URLPatternsTestCase, TestCase): response = self.client.delete(reverse('basic-action3', args=[1])) assert response.data == {'delete': '1'} + def test_register_after_accessing_urls(self): + self.router.register(r'notes', NoteViewSet) + assert len(self.router.urls) == 2 # list and detail + self.router.register(r'notes_bis', NoteViewSet) + assert len(self.router.urls) == 4 + class TestRootView(URLPatternsTestCase, TestCase): urlpatterns = [