Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Декоратор @action в Django REST Framework
Декоратор @action используется для определения кастомных действий (эндпоинтов) в ViewSets, помимо стандартных CRUD операций (list, create, retrieve, update, destroy).
Основное назначение
@action нужен для:
- Добавления custom endpoints: специфичные для бизнеса операции
- Расширения ViewSet: без создания отдельного View
- RESTful API: соблюдение REST принципов
- Маршрутизации: автоматическое создание URL
Синтаксис
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
class ArticleViewSet(ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
@action(detail=True, methods=['post'])
def publish(self, request, pk=None):
article = self.get_object()
article.is_published = True
article.save()
return Response({'status': 'article published'})
Параметры декоратора
detail=True vs detail=False:
Точка в том, что есть две категории действий:
- detail=True применяется к конкретному объекту: /articles/{id}/publish/
- detail=False применяется ко всей коллекции: /articles/top_products/
class ProductViewSet(ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
@action(detail=True, methods=['post'])
def add_to_cart(self, request, pk=None):
product = self.get_object()
return Response({'status': 'added'})
@action(detail=False, methods=['get'])
def top_products(self, request):
top = Product.objects.filter(rating__gte=4.5)[:10]
serializer = self.get_serializer(top, many=True)
return Response(serializer.data)
Практические примеры
Публикация статей:
from rest_framework import status
class ArticleViewSet(ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
@action(detail=True, methods=['post'])
def publish(self, request, pk=None):
article = self.get_object()
if not article.title or not article.content:
return Response(
{'error': 'Missing required fields'},
status=status.HTTP_400_BAD_REQUEST
)
article.is_published = True
article.published_at = timezone.now()
article.save()
serializer = self.get_serializer(article)
return Response(serializer.data)
Лайк/Unlike:
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
@action(detail=True, methods=['post'])
def like(self, request, pk=None):
post = self.get_object()
user = request.user
if post.likes.filter(id=user.id).exists():
return Response(
{'error': 'Already liked'},
status=status.HTTP_400_BAD_REQUEST
)
post.likes.add(user)
return Response({
'status': 'liked',
'likes_count': post.likes.count()
})
@action(detail=True, methods=['post'])
def unlike(self, request, pk=None):
post = self.get_object()
post.likes.remove(request.user)
return Response({
'status': 'unliked',
'likes_count': post.likes.count()
})
URL маршрутизация
from django.urls import path, include
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'articles', ArticleViewSet)
urlpatterns = [
path('api/', include(router.urls)),
]
Автоматически созданные URLs:
- GET /api/articles/ - list
- POST /api/articles/ - create
- GET /api/articles/{id}/ - retrieve
- PUT /api/articles/{id}/ - update
- DELETE /api/articles/{id}/ - destroy
- POST /api/articles/{id}/publish/ - наш @action
Дополнительные параметры
@action(
detail=True,
methods=['post'],
url_path='publish-article',
url_name='article-publish',
permission_classes=[IsAuthenticated],
)
def publish(self, request, pk=None):
pass
Проверка прав доступа
from rest_framework.permissions import IsAuthenticated, IsAdminUser
@action(
detail=True,
methods=['post'],
permission_classes=[IsAdminUser]
)
def approve(self, request, pk=None):
# Только администраторы могут вызвать
pass
Выводы
- @action добавляет custom endpoints к ViewSet
- detail=True: действие над конкретным объектом
- detail=False: действие над коллекцией
- methods: определяет HTTP методы (get, post, put, delete)
- Автоматическая маршрутизация: URLs создаются роутером
- RESTful: соблюдает REST принципы
- Полезно для: бизнес-логики, не подходящей под стандартные CRUD операции