path, re_path, include, namespace, reverse, get_object_or_404
Система маршрутизации Django (URLconf) преобразует URL запроса в Python функцию (view). Понимание URLconf критично для создания чистых и поддерживаемых URL.
💡 Правило: URL должны быть читаемыми и семантическими. Используйте именованные группы для передачи параметров в view.
# project/urls.py
from django.urls import path
from . import views
urlpatterns = [
# Базовый маршрут
path('articles/', views.article_list, name='article_list'),
# С параметром
path('articles/<int:pk>/', views.article_detail, name='article_detail'),
# С несколькими параметрами
path('articles/<int:year>/<slug:slug>/', views.article_by_date, name='article_by_date'),
# Без параметра (главная страница)
path('', views.home, name='home'),
]| Тип | Описание | Пример |
|---|---|---|
str | Любая строка без / (по умолчанию) | <slug:article_slug> |
int | Любое целое положительное число | <int:year> |
slug | Slug строка (буквы, цифры, дефис, подчёркивание) | <slug:slug> |
uuid | UUID строка | <uuid:id> |
path | Любая строка включая / | <path:file_path> |
# Примеры использования
path('posts/<int:year>/', views.year_archive) # posts/2026/
path('posts/<slug:slug>/', views.post_detail) # posts/my-first-post/
path('files/<path:file_path>/', views.serve_file) # files/docs/manual.pdf
path('items/<uuid:id>/', views.item_detail) # items/123e4567-e89b-12d3-a456-426614174000/from django.urls import re_path
urlpatterns = [
# Сложный паттерн с опциональными параметрами
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})?/$', views.archive),
# Точное совпадение с концом строки
re_path(r'^about/$', views.about),
# Несколько форматов
re_path(r'^download/(?P<path>.+)\.(?P<format>pdf|epub|mob i)$', views.download),
]# ✅ path() — читаемо
path('articles/<int:pk>/', views.detail)
# ⚠️ re_path() — сложнее, но гибче
re_path(r'^articles/(?P<pk>[0-9]+)/$', views.detail)
# ✅ path() предпочтительнее для простых случаев
# ⚠️ re_path() для сложных regex паттернов# project/urls.py
from django.urls import path, include
urlpatterns = [
path('', views.home, name='home'),
path('admin/', admin.site.urls),
# Подключение приложений
path('articles/', include('articles.urls')),
path('users/', include('users.urls')),
path('api/', include('api.urls')),
# Auth URLs
path('accounts/', include('django.contrib.auth.urls')),
]# articles/urls.py
from django.urls import path
from . import views
app_name = 'articles' # Namespace для reverse()
urlpatterns = [
path('', views.list, name='list'),
path('<int:pk>/', views.detail, name='detail'),
path('create/', views.create, name='create'),
path('<int:pk>/edit/', views.edit, name='edit'),
path('<int:pk>/delete/', views.delete, name='delete'),
]# project/urls.py
urlpatterns = [
path('blog/', include([
path('', views.blog_home, name='blog_home'),
path('posts/', include([
path('', views.post_list, name='post_list'),
path('<int:pk>/', views.post_detail, name='post_detail'),
])),
path('authors/', include('authors.urls')),
])),
]# articles/urls.py
app_name = 'articles'
urlpatterns = [
path('', views.list, name='list'),
path('<int:pk>/', views.detail, name='detail'),
]
# blog/urls.py
app_name = 'blog'
urlpatterns = [
path('', views.list, name='list'), # То же имя, другой namespace
path('<int:pk>/', views.detail, name='detail'),
]from django.urls import reverse
# Без namespace (уникальное имя)
url = reverse('home') # '/'
# С namespace
url = reverse('articles:list') # '/articles/'
url = reverse('articles:detail', kwargs={'pk': 5}) # '/articles/5/'
url = reverse('blog:list') # '/blog/'
# В шаблонах
# {% url 'articles:detail' pk=5 %}
# {% url 'articles:list' %}# Для множественных экземпляров одного приложения
# urls.py
path('author1/', include('articles.urls', namespace='author1_articles')),
path('author2/', include('articles.urls', namespace='author2_articles')),
# reverse()
reverse('author1_articles:detail', kwargs={'pk': 5})from django.urls import reverse
from django.http import HttpResponseRedirect
def create_article(request):
if request.method == 'POST':
# Обработка формы
article = Article.objects.create(title=title, content=content)
# Редирект после создания
return HttpResponseRedirect(reverse('articles:detail', kwargs={'pk': article.pk}))
return render(request, 'articles/create.html')from django.urls import reverse_lazy
from django.views.generic import CreateView
class ArticleCreateView(CreateView):
model = Article
fields = ['title', 'content']
success_url = reverse_lazy('articles:list') # lazy вычисление при использованииfrom django.shortcuts import redirect
# По имени URL
return redirect('articles:detail', pk=5)
# По объекту (если get_absolute_url() определён)
return redirect(article)
# По URL строке
return redirect('/articles/')
# С query параметрами
return redirect(f'/articles/?page={page_number}')from django.shortcuts import get_object_or_404
def article_detail(request, pk):
article = get_object_or_404(Article, pk=pk)
return render(request, 'articles/detail.html', {'article': article})from django.http import Http404
def article_detail(request, pk):
try:
article = Article.objects.get(pk=pk)
except Article.DoesNotExist:
raise Http404("Article does not exist")
return render(request, 'articles/detail.html', {'article': article})# Несколько условий
article = get_object_or_404(
Article,
pk=pk,
is_published=True,
author=request.user
)
# С связанными объектами
article = get_object_or_404(
Article.objects.select_related('author'),
pk=pk,
is_published=True
)from django.shortcuts import get_list_or_404
def articles_by_category(request, category_slug):
articles = get_list_or_404(
Article,
category__slug=category_slug,
is_published=True
)
return render(request, 'articles/list.html', {'articles': articles})# urls.py
path('articles/', views.list, {'template_name': 'articles/custom.html'}),
# views.py
def list(request, template_name='articles/list.html'):
return render(request, template_name, {'articles': Article.objects.all()})# converters.py
class YearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return str(value).zfill(4)
class MonthConverter:
regex = '[0-9]{1,2}'
def to_python(self, value):
if not 1 <= int(value) <= 12:
raise ValueError('Month must be between 1 and 12')
return int(value)
def to_url(self, value):
return str(value)
# urls.py
from django.urls import register_converter, path
from . import converters, views
register_converter(converters.YearConverter, 'year')
register_converter(converters.MonthConverter, 'month')
urlpatterns = [
path('articles/<year:year>/<month:month>/', views.archive),
]from django.urls import resolve
# Получить view функцию по URL
match = resolve('/articles/5/')
print(match.func) # <function article_detail at 0x...>
print(match.kwargs) # {'pk': 5}
print(match.url_name) # 'article_detail'
print(match.app_names) # ['articles']# blog/urls.py
from django.urls import path, include
from . import views
app_name = 'blog'
urlpatterns = [
# Главная страница блога
path('', views.PostListView.as_view(), name='home'),
# Посты
path('posts/', include([
path('', views.PostListView.as_view(), name='post_list'),
path('new/', views.PostCreateView.as_view(), name='post_create'),
path('<int:pk>/', views.PostDetailView.as_view(), name='post_detail'),
path('<int:pk>/edit/', views.PostUpdateView.as_view(), name='post_edit'),
path('<int:pk>/delete/', views.PostDeleteView.as_view(), name='post_delete'),
])),
# Категории
path('categories/', include([
path('', views.CategoryListView.as_view(), name='category_list'),
path('<slug:slug>/', views.CategoryDetailView.as_view(), name='category_detail'),
])),
# Теги
path('tags/', include([
path('', views.TagListView.as_view(), name='tag_list'),
path('<slug:slug>/', views.TagDetailView.as_view(), name='tag_detail'),
])),
# Авторы
path('authors/<int:pk>/', views.AuthorDetailView.as_view(), name='author_detail'),
# Архив по датам
path('archive/', include([
path('<int:year>/', views.YearArchiveView.as_view(), name='archive_year'),
path('<int:year>/<int:month>/', views.MonthArchiveView.as_view(), name='archive_month'),
path('<int:year>/<int:month>/<int:day>/', views.DayArchiveView.as_view(), name='archive_day'),
])),
# Поиск
path('search/', views.search, name='search'),
# RSS
path('feed/', include('django.contrib.syndication.views')),
]# project/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', include('blog.urls', namespace='blog')),
path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')),
path('api/', include('api.urls')),
]
# Статические файлы в debug режиме
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.