SyntaxStudy
Sign Up
Django URL Patterns and path() vs re_path()
Django Beginner 1 min read

URL Patterns and path() vs re_path()

URL configuration in Django is done through Python lists named urlpatterns. Each entry maps a URL pattern to a view. The path() function is the recommended way to define URL patterns. It supports typed path converters — , , , , — that both match the URL and convert the captured value to the appropriate Python type before passing it to the view. The re_path() function accepts a regular expression pattern for cases where path() converters are insufficient. Regular expressions offer full flexibility but are harder to read. A common use case is matching multiple URL formats or applying complex validation to captured groups. For most applications, path() with converters covers all common patterns without the complexity of regular expressions. The name parameter on path() and re_path() assigns a unique identifier to the URL. Named URLs let you generate URLs from view names using the reverse() function in Python code or the {% url %} tag in templates. This means changing a URL pattern in urls.py automatically updates all links across your application — you never hardcode URLs in templates or views.
Example
# blog/urls.py — URL patterns
from django.urls import path, re_path
from . import views

app_name = 'blog'  # sets the application namespace

urlpatterns = [
    # path() with typed converters
    path('',                         views.PostListView.as_view(),   name='post-list'),
    path('<int:pk>/',                 views.PostDetailView.as_view(), name='post-detail'),
    path('<int:pk>/edit/',            views.PostUpdateView.as_view(), name='post-update'),
    path('<int:pk>/delete/',          views.PostDeleteView.as_view(), name='post-delete'),
    path('create/',                   views.PostCreateView.as_view(), name='post-create'),
    path('tag/<slug:tag_slug>/',      views.PostListView.as_view(),   name='posts-by-tag'),

    # re_path() for a date-based archive URL
    re_path(
        r'^archive/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',
        views.PostArchiveView.as_view(),
        name='post-archive',
    ),
]

# mysite/urls.py — root URL configuration
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/',  admin.site.urls),
    path('blog/',   include('blog.urls', namespace='blog')),
    path('accounts/', include('django.contrib.auth.urls')),
]

# Generating URLs in Python
from django.urls import reverse
url = reverse('blog:post-detail', kwargs={'pk': 42})
# -> '/blog/42/'

# Generating URLs in templates
# {% url 'blog:post-detail' pk=post.pk %}
# {% url 'blog:posts-by-tag' tag_slug=tag.slug %}