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.
This commit is contained in:
Sébastien Diemer 2019-01-17 14:07:57 +01:00 committed by Tom Christie
parent c049777dc7
commit 822b85ac36
2 changed files with 10 additions and 0 deletions

View File

@ -100,6 +100,10 @@ class BaseRouter(six.with_metaclass(RenameRouterMethods)):
basename = self.get_default_basename(viewset) basename = self.get_default_basename(viewset)
self.registry.append((prefix, viewset, basename)) self.registry.append((prefix, viewset, basename))
# invalidate the urls cache
if hasattr(self, '_urls'):
del self._urls
def get_default_basename(self, viewset): def get_default_basename(self, viewset):
""" """
If `basename` is not specified, attempt to automatically determine If `basename` is not specified, attempt to automatically determine

View File

@ -158,6 +158,12 @@ class TestSimpleRouter(URLPatternsTestCase, TestCase):
response = self.client.delete(reverse('basic-action3', args=[1])) response = self.client.delete(reverse('basic-action3', args=[1]))
assert response.data == {'delete': '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): class TestRootView(URLPatternsTestCase, TestCase):
urlpatterns = [ urlpatterns = [