Fork me on GitHub

The reverse(…) function [Django-doc] allows to pass the names of views as well as references to functions. Indeed, for example with:

#app_name/urls.py

from app_name.views import some_view

urlpatterns = [
    path('some-path', some_view, name='something'),
]

and then determine the path with reverse(some_view).

Why is it a problem?

Django determines the reverse URL with some quite complicated and chaotic logic, where ech URLResolver has a .reverse_dict. A path(…) for example with an include(…) [Django-doc], has its own .reverse_dict.

The problem starts to arise when app_name is used. In that case, it does not "backpropagate" content to the parent .reverse_dict. This thus means that the parent dictionary will not contain entries to these view function references, and therefore can not reverse these. The problem is most severe when an (independent) Django app does that, since then we don't have control if someone later includes the paths in the Django app with an app name specified.

Since we thus have no control over that, using the reference to reverse was probably a misfeature of Django in the first place.

What can be done to resolve the problem?

Name the paths, and use the (namespaced) app. Of course even that has a problem, since again we don't know when a view will eventually get namespaced. Using the view handler could have been used as a unique way to reference to a path, but at the moment it is not, so as for now, we need to work with the "collapsed structure" of referencing by name.

We thus don't work with reverse(some_view), but with reverse('something'), with the app_name as prefix if that is defined.