Для чего используется декоратор @action в Django REST Framework

Ответ

Декоратор @action в Django REST Framework (DRF) используется для добавления пользовательских маршрутов (эндпоинтов) к стандартному набору ViewSet.

Стандартный ViewSet предоставляет CRUD-операции (list, create, retrieve, update, destroy). Если требуется дополнительная логика, не вписывающаяся в CRUD, на помощь приходит @action.

Ключевой параметр — detail:

  • detail=True: Действие применяется к конкретному объекту. URL будет содержать pk объекта. Например, POST /users/1/set_password/.
  • detail=False: Действие применяется ко всему набору объектов (коллекции). URL не будет содержать pk. Например, GET /users/active_users/.

Пример:

Добавим эндпоинт для смены пароля конкретного пользователя и эндпоинт для получения всех активных пользователей.

from django.contrib.auth.models import User
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from .serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    # Действие для конкретного объекта (пользователя)
    # URL: /users/{pk}/set_password/
    @action(detail=True, methods=['post'])
    def set_password(self, request, pk=None):
        user = self.get_object()
        password = request.data.get('password')
        if not password:
            return Response({'error': 'Password not provided'}, status=status.HTTP_400_BAD_REQUEST)

        user.set_password(password)
        user.save()
        return Response({'status': 'password set'})

    # Действие для всей коллекции
    # URL: /users/active_users/
    @action(detail=False, methods=['get'])
    def active_users(self, request):
        active_users = User.objects.filter(is_active=True)
        serializer = self.get_serializer(active_users, many=True)
        return Response(serializer.data)

Основные параметры @action:

  • detail (bool): Определяет, привязан ли маршрут к объекту или коллекции.
  • methods (list): Список разрешенных HTTP-методов (e.g., ['get', 'post']).
  • url_path (str): Позволяет задать кастомный сегмент URL вместо имени функции.
  • url_name (str): Имя для реверсирования URL (reverse()).