Search code examples
djangodjango-urlsdjango-apps

Is it OK use multiple empty routes in Django URL patterns?


One of my project's app's url.py includes url files from other apps. Is there any issue I'm overlooking by including them with empty routes? e.g.:

In appA urls.py:

urlpatterns = [
    path('hub/', views.hub, name='hub'),
    path('dashboard/', views.dashboard, name='dashboard'),
    path('', views.hub_redirect),  # Redirects / to /hub/
    path('', include('appB.urls')),
    path('', include('appC.urls')),
]

Where appB.urls and appC.urls all contain paths each with a defined unique route (i.e., not ''). It works! But now wondering if it should...

I've not seen any documentation saying that non-empty routes are required, but concerned now about best practice. I'm also concerned that I'm not understanding the function of apps. When I use django-admin createapp the urls.py is not automatically generated, so it makes me wonder if I should keep urls all on appA and point them to the views of appB and appC, but my current way makes sense to me (as it would be easier to refactor a URL within the app of the related functionality without having to make changes ouside, i.e. in appA).


Solution

  • Where appB.urls and appC.urls all contain paths each with a defined unique route.

    Yes, that is perfectly fine. Django tries to match the request path by enumerating over the paths top-to-bottom, and will fire the first path that matches.

    This thus means that if two paths overlap, by using an include include(…) [Django-doc], or just two .path(…) [Django-doc], then it will pick the first one. Adding these in two different include(…)s of course will complicate the matter a bit, since now the paths are defined in different files, making it harder to reason about it. Especially if you include the paths of an app you have no control about, eventually the package might introduce new paths, and so an overlap can occur.

    So as a rule of thumb, it is often better to work with non-overlapping includes, but it is not per se a problem not to do so.