from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.PostListView.as_view(), name='post_list'),
path('post/<int:pk>/', views.PostDetailView.as_view(), name='post_detail'),
path('post/new/', views.PostCreateView.as_view(), name='post_create'),
path('post/<int:pk>/edit/', views.PostUpdateView.as_view(), name='post_edit'),
path('post/<int:pk>/delete/', views.PostDeleteView.as_view(), name='post_delete'),
path('category/<slug:slug>/', views.CategoryView.as_view(), name='category'),
]
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('api/', include('api.urls', namespace='api')),
]
from django.urls import reverse
from django.shortcuts import redirect
def some_view(request):
# Reverse with args
url = reverse('blog:post_detail', args=[123])
# Reverse with kwargs
url = reverse('blog:category', kwargs={'slug': 'django'})
# Absolute URL
absolute_url = request.build_absolute_uri(reverse('blog:post_list'))
return redirect('blog:post_list')
URL namespaces prevent name collisions across apps. I set app_name in app-level urls.py and use namespace in include(). Reverse lookups use reverse('namespace:name') or {% url 'namespace:name' %} in templates. This makes URLs maintainable when refactoring. I pass arguments to reverse() as args or kwargs. For absolute URLs, I use request.build_absolute_uri(reverse(...)). URL namespacing is essential for reusable Django apps. I keep URL patterns organized by feature or resource type.