Views10 temas

Views

DRF ofrece varias capas de abstracción para escribir views. La clave está en entender cuándo usar cada una.

APIView — control total

APIView es la clase base de todas las vistas de DRF. Cada verbo HTTP es un método: get(), post(), put(), delete().

  • Request/response a mano: sin queryset ni serializer automático
  • Soporte de DRF incluido: parsing, autenticación, permisos, throttling

Usar cuando el endpoint no es CRUD de un modelo: procesar un pago, exportar un archivo, ejecutar una tarea.

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status


class ProcesarPagoView(APIView):
    def post(self, request):
        monto = request.data.get("monto")
        if not monto:
            return Response(
                {"error": "monto requerido"},
                status=status.HTTP_400_BAD_REQUEST,
            )
        # lógica de negocio...
        return Response({"ok": True}, status=status.HTTP_200_OK)
  • Trade-off: Control absoluto, pero se escribe todo, incluso lo repetitivo

GenericAPIView — la base reutilizable

GenericAPIView es APIView con infraestructura para modelos y serializers: se declaran queryset y serializer_class, y la vista provee los métodos que los usan.

Método Qué hace
get_queryset() Devuelve el queryset declarado
get_serializer_class() Devuelve el serializer declarado
get_object() Busca un objeto por pk dentro del queryset
from rest_framework import generics


class ProductListView(generics.ListAPIView):
    """
    ListAPIView ya trae ListModelMixin + GenericAPIView.
    Solo definís queryset y serializer.
    """
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

Vistas concretas incluidas: GenericAPIView + mixins ya combinados. Solo se definen queryset y serializer_class.

Vista Mixin que usa
ListAPIView ListModelMixin
CreateAPIView CreateModelMixin
RetrieveAPIView RetrieveModelMixin
UpdateAPIView UpdateModelMixin
DestroyAPIView DestroyModelMixin
ListCreateAPIView ListModelMixin + CreateModelMixin
RetrieveUpdateDestroyAPIView RetrieveModelMixin + UpdateModelMixin + DestroyModelMixin
Cuidado:

GenericAPIView sola no responde ningún verbo HTTP. Siempre se combina con mixins o vistas concretas.

Mixins — composición exacta

Un mixin implementa una única acción CRUD sobre los helpers de GenericAPIView. Para armar una vista se hereda GenericAPIView + los mixins de las acciones que se quieren exponer.

from rest_framework import mixins, generics


class ProductListCreateView(
    mixins.ListModelMixin,
    mixins.CreateModelMixin,
    generics.GenericAPIView,
):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
Mixin HTTP Acción
ListModelMixin GET Listar colección
CreateModelMixin POST Crear recurso
RetrieveModelMixin GET Obtener un recurso
UpdateModelMixin PUT / PATCH Actualizar recurso
DestroyModelMixin DELETE Eliminar recurso
  • Trade-off: Más control que un ViewSet, pero más código boilerplate

Casos de uso

Para… Usar
Control total, lógica custom APIView
CRUD de un modelo pero sin magia GenericAPIView + mixins específicos
Solo list + retrieve (read-only) GenericAPIView + ListModelMixin + RetrieveModelMixin
Un endpoint que no es CRUD APIView directamente

Buenas prácticas

Práctica Por qué
Empezar con la vista concreta (ListAPIView) Si después se necesita más, se agregan mixins
No temer bajar a APIView Forzar una vista genérica donde no va es peor
perform_create() para lógica extra Más limpio que reescribir create() entero

Resumen

APIView es la base. GenericAPIView ahorra el boilerplate de queryset/serializer. Los mixins permiten armar combinaciones exactas. Y las vistas concretas (ListAPIView, etc.) son el atajo para el 90% de los casos.

Recursos

DRF Docs: Generic Views