Disclaimer: this is a minimal reproducible example, my actual code is a lot more complicated.
Consider the following test:
from django.urls import reverse
def test_foo():
url = reverse("my_app:foo")
assert url == "/my_app/foo/"
Everything is configured properly and the test passes.
Now I have different test, with the following code:
from django.contrib import admin
from django.urls import reverse
from tests.test_app.models import TestModel
def test_bar():
admin.site.register(TestModel, admin.ModelAdmin)
url = reverse("admin:test_app_testmodel_changelist")
assert url == "/admin/test_app/testmodel/"
This test, when run alone or before test_foo()
, passes.
However, if test_bar()
is run after test_foo()
, then it fails with an exception django.urls.exceptions.NoReverseMatch: Reverse for 'test_app_testmodel_changelist' not found. 'test_app_testmodel_changelist' is not a valid view function or pattern name.
This example can be simplified:
def test_baz_passes():
admin.site.register(TestModel, admin.ModelAdmin)
url = reverse("myapp:foo")
url = reverse("admin:test_app_testmodel_changelist")
def test_baz_fails():
url = reverse("myapp:foo")
admin.site.register(TestModel, admin.ModelAdmin)
url = reverse("admin:test_app_testmodel_changelist")
Clearly there are some side effects (caches?) done in urls.reverse()
, which are not reversed/cleared by registering admin app. The result is that subsequent calls to reverse()
don’t find new urls provided by ModelAdmin
. I did try to run clear_url_caches()
after registering site, but it does not help.
I’ve found one ticket comment that vaguely resembles this case, but I’m not sure if that is helpful.
Is this a bug?