Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Роутинг
routing

Роутинг

SimpleRouter, DefaultRouter, кастомные роутеры, URL-конфигурация

Роутинг в Django REST Framework

Роутеры DRF автоматически генерируют URL-паттерны для ViewSets, избавляя от необходимости вручную прописывать каждый путь.

#Простой роутинг с SimpleRouter

SimpleRouter создаёт базовые URL-паттерны для ViewSet:

# urls.py from rest_framework.routers import SimpleRouter from .views import ArticleViewSet router = SimpleRouter() router.register(r'articles', ArticleViewSet, basename='article') urlpatterns = router.urls

Сгенерированные паттерны:

URLМетодДействиеИмя URL
/articles/GETlistarticle-list
/articles/POSTcreatearticle-list
/articles/{pk}/GETretrievearticle-detail
/articles/{pk}/PUTupdatearticle-detail
/articles/{pk}/PATCHpartial_updatearticle-detail
/articles/{pk}/DELETEdestroyarticle-detail

Параметры register():

  • prefix — префикс URL (например, 'articles')
  • viewset — класс ViewSet
  • basename — базовое имя для reverse (опционально, по умолчанию от названия viewset)

#DefaultRouter с API root

DefaultRouter добавляет автоматический API root view:

from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'articles', ArticleViewSet, basename='article') router.register(r'users', UserViewSet, basename='user') urlpatterns = [ path('api/', include(router.urls)), ]

Особенности DefaultRouter:

  • Создаёт корневую страницу API (/api/) со списком всех endpoints
  • Добавляет формат .json, .api к URL
  • Включает BrowsableAPIRenderer по умолчанию

Пример API root:

{ "articles": "http://example.com/api/articles/", "users": "http://example.com/api/users/" }

#Кастомизация роутера

Можно создать свой роутер, наследуясь от SimpleRouter или DefaultRouter:

from rest_framework.routers import DefaultRouter class CustomRouter(DefaultRouter): """Кастомный роутер с дополнительными настройками""" trailing_slash = False # URL без завершающего слэша def get_default_basename(self, viewset): """Кастомное имя basename по умолчанию""" if self.basename_regex: return re.sub(self.basename_regex, '', viewset.__name__) return super().get_default_basename(viewset) router = CustomRouter() router.register(r'articles', ArticleViewSet) # URL: /articles (без слэша в конце)

#Вложенные роутеры

Для вложенных ресурсов (например, комментарии к статье) используйте drf-nested-routers:

pip install drf-nested-routers
# urls.py from rest_framework.routers import DefaultRouter from rest_framework_nested.routers import NestedDefaultRouter from .views import ArticleViewSet, CommentViewSet router = DefaultRouter() router.register(r'articles', ArticleViewSet, basename='article') # Вложенный роутер для комментариев articles_router = NestedDefaultRouter(router, r'articles', lookup='article') articles_router.register(r'comments', CommentViewSet, basename='article-comments') urlpatterns = [ path('api/', include(router.urls)), path('api/', include(articles_router.urls)), ]

Сгенерированные URL:

URLДействие
/api/articles/Список статей
/api/articles/{pk}/Одна статья
/api/articles/{article_pk}/comments/Список комментариев к статье
/api/articles/{article_pk}/comments/{pk}/Один комментарий

Использование в ViewSet:

class CommentViewSet(viewsets.ModelViewSet): serializer_class = CommentSerializer def get_queryset(self): # Фильтруем комментарии по статье article_pk = self.kwargs['article_pk'] return Comment.objects.filter(article_id=article_pk) def perform_create(self, serializer): # Автоматически устанавливаем статью article_pk = self.kwargs['article_pk'] serializer.save(article_id=article_pk)

#Ручной роутинг без роутеров

Можно использовать обычные Django URL patterns:

# urls.py from django.urls import path from .views import ArticleList, ArticleDetail urlpatterns = [ path('api/articles/', ArticleList.as_view(), name='article-list'), path('api/articles/<int:pk>/', ArticleDetail.as_view(), name='article-detail'), ]

Когда использовать ручной роутинг:

  • Нестандартные URL-паттерны
  • Function-based views без ViewSets
  • Полный контроль над URL

#Гиперсвязанные представления

HyperlinkedModelSerializer использует URL вместо первичных ключей:

# serializers.py class ArticleSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Article fields = ['url', 'title', 'content', 'author'] # 'url' — гиперссылка на детальное представление # views.py class ArticleViewSet(viewsets.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer

Пример ответа:

{ "url": "http://example.com/api/articles/1/", "title": "Моя статья", "content": "Текст статьи", "author": "http://example.com/api/users/5/" }

Настройка lookup field:

class ArticleViewSet(viewsets.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer lookup_field = 'slug' # Использовать slug вместо pk # URL: /articles/my-article-slug/

#Reverse и получение URL

#В коде

from django.urls import reverse # Получить URL для list url = reverse('article-list') # '/api/articles/' # Получить URL для detail url = reverse('article-detail', kwargs={'pk': 1}) # '/api/articles/1/'

#В шаблонах

<a href="{% url 'article-list' %}">Список статей</a> <a href="{% url 'article-detail' pk=1 %}">Статья 1</a>

#В сериализаторах

class ArticleSerializer(serializers.ModelSerializer): url = serializers.SerializerMethodField() def get_url(self, obj): request = self.context['request'] return request.build_absolute_uri( reverse('article-detail', kwargs={'pk': obj.pk}) )

#Namespaces

Для разделения API на версии или модули используйте namespaces:

# urls.py urlpatterns = [ path('api/v1/', include((router.urls, 'api'), namespace='v1')), path('api/v2/', include((router.urls, 'api'), namespace='v2')), ] # В коде reverse('v1:article-list') # '/api/v1/articles/' reverse('v2:article-list') # '/api/v2/articles/'

#Best Practices

  1. Используйте DefaultRouter для стандартных API — даёт API root автоматически
  2. Указывайте basename явно при register() для предсказуемых имён URL
  3. drf-nested-routers для вложенных ресурсов — чистые URL вида /articles/{id}/comments/
  4. lookup_field для человеко-читаемых URL — /articles/my-slug/ вместо /articles/1/
  5. Namespaces для версионирования — /api/v1/, /api/v2/

Далее: Аутентификация