Create equivalent paths in Django urls.py

Viewed 72

I am attempting to create 2 url prefixes that would be equivalent in my app (this is due to some aesthetic user requirements), and am unsure the best way to go about this. The most straightforward option would be to create another set of urlpatterns with the alternate prefix. However, this would be repetitive and make maintenance more difficult. Is there a simpler way to make foo/<str:key>/ equivalent to bar/<str:key> and staff/<str:key>/ equivalent to foo/<str:key>/staff/?

Current URLS

urlpatterns = [
    path('foo/<str:key>/welcome/', views.welcome),
    path('foo/<str:key>/dashboard/', views.dashboard),
    path('foo/<str:key>/staff/dashboard/', views.staff_dashboard),
]

Desired Patterns

urlpatterns = [
    # Original paths
    path('foo/<str:key>/welcome/', views.welcome),
    path('foo/<str:key>/dashboard/', views.dashboard),
    path('foo/<str:key>/staff/dashboard/', views.staff_dashboard),

    # Alternate paths to the same pages
    path('bar/<str:key>/welcome/', views.welcome),
    path('bar/<str:key>/dashboard/', views.dashboard),
    path('staff/<str:key>/dashboard/', views.staff_dashboard),
]
1 Answers

You can define the set of paths once, and then include these twice:

from django.urls import include, path

sub_paths = [
    path('welcome/', views.welcome),
    path('dashboard/', views.dashboard),
    path('staff/dashboard/', views.staff_dashboard),
]

urlpatterns = [
    path('foo/<str:key>/', include(sub_paths)),
    path('bar/<str:key>/', include(sub_paths)),
    path('staff/<str:key>/dashboard/', views.staff_dashboard),
]

We thus define the paths for foo/ and bar once in a single list, and then reuse these multiple times.

That being said, it is advisable that each view (with parameters) maps to a single path and vice versa. It makes it clear that two different paths will go to different views, and when reversing the view, it is clear what the outcome will be.

Related