Creación de una API REST con Django Rest Framework

Django Rest Framework (DRF) es un potente framework basado en Django para crear APIs RESTful de manera sencilla y escalable. Facilita la serialización de datos, la gestión de autenticación y permisos, y la implementación de buenas prácticas REST. Es clave en el desarrollo moderno, permitiendo la integración eficiente con frontend y otros servicios. 🚀

Requisitos Previos

  • Python 3.x o superior
  • pip (gestor de paquetes de Python)
  • virtualenv (para gestión de entornos virtuales) - Crear entorno

Instalación de Herramientas

bash
# Verificar versión de Python
python --version

# Instalar virtualenv
pip install virtualenv

Configuración del Entorno Virtual

bash
# Crear directorio para el proyecto
mkdir mi_proyecto_api
cd mi_proyecto_api

# Crear entorno virtual
python -m venv venv

# Activar entorno virtual
# En sistemas Unix/macOS
source venv/bin/activate

# En Windows
venv/Scripts/activate

Instalar Django y Django Rest Framework (DRF)

bash
# Instalar Django y DRF
pip install django djangorestframework

# Crear archivo de requirements
pip freeze > requirements.txt

Verifica la instalación de Django

bash
django-admin --version

Deberías ver la versión de Django instalada.

Crear Proyecto Django


bash
# Crear nuevo proyecto Django
django-admin startproject config .

# Crear aplicación para la API
python manage.py startapp api

1. Configuración de Settings

En config/settings.py, añadir las aplicaciones:

python
INSTALLED_APPS = [
  'django.contrib.admin',
  'django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.messages',
  'django.contrib.staticfiles',
  
  # Aplicaciones de terceros
  'rest_framework',
  
  # Aplicaciones propias
  'api',
]

2. Diseño de Modelos

Crea un modelo en la aplicación api que quieres exponer como parte de la API. Abre api/models.py y define el siguiente modelo de ejemplo:

python
from django.db import models

class Libro(models.Model):
  titulo = models.CharField(max_length=200)
  autor = models.CharField(max_length=100)
  publicacion = models.DateField()
  isbn = models.CharField(max_length=13, unique=True)
  
  def __str__(self):
      return self.titulo

3. Crear Migraciones

Crea las migraciones y aplica los cambios a la base de datos:

bash
# Crear migraciones
python manage.py makemigrations

# Aplicar migraciones
python manage.py migrate

4. Definir los Serializadores en serializers.py

En DRF, los serializadores convierten los datos de los modelos en formatos como JSON para enviarlos a través de la API.

Crea un archivo llamado serializers.py dentro de la carpeta api y define el serializador para el modelo Libro:

python
# importar DRF serializers
from rest_framework import serializers
# importar el modelo
from .models import Libro

# Definir el serializador de Libro
class LibroSerializer(serializers.ModelSerializer):
  class Meta:
      model = Libro
      fields = ['id', 'titulo', 'autor', 'publicacion', 'isbn']

      # Tambien puedes  usar fields = '__all__' para serializar todos los campos

5. Registrar el Modelo en Django Admin

Añade el modelo Libro al panel de administración de Django para gestionarlo desde la interfaz administrativa, este lo puedes conseguier en el archivo api/admin.py:

python
from django.contrib import admin
# importar el modelo Libro
from .models import Libro

admin.site.register(Libro)

6. Vistas (Views)

En Django Rest Framework (DRF), existen dos enfoques para definir vistas: vistas basadas en funciones (FBV) y vistas basadas en clases (CBV). Ambos permiten manejar solicitudes HTTP (GET, POST, PUT, DELETE), pero ofrecen distintos niveles de abstracción y flexibilidad.

Vistas basadas en clases (CBV)


Las vistas basadas en clases proporcionan una estructura más organizada y reutilizable. DRF ofrece ViewSets, que simplifican la creación de APIs RESTful.

Ejemplo: api/views.py
python
from rest_framework import viewsets
from .models import Libro
from .serializers import LibroSerializer

class LibroViewSet(viewsets.ModelViewSet):
  queryset = Libro.objects.all()
  serializer_class = LibroSerializer

Vistas Basadas en Funciones (FBV)


Las vistas basadas en funciones son más directas y fáciles de entender, lo que las hace ideales para proyectos pequeños o para quienes buscan mayor flexibilidad en el manejo de solicitudes. Su simplicidad facilita la depuración y personalización del flujo de datos.

Ejemplo: api/views.py

bash
# Importar decoradores de API REST
from rest_framework.decorators import api_view
# Importar Response para manejar respuestas
from rest_framework.response import Response
# Importar el modelo Libro
from .models import Libro
# Importar el serializador LibroSerializer para convertir datos en JSON
from .serializers import LibroSerializer


# Vista para listar y crear libros
@api_view(['GET', 'POST'])
def libro_list(request):
  if request.method == 'GET':
      # Obtener todos los libros de la base de datos
      libros = Libro.objects.all()
      # Serializar los datos para devolverlos en formato JSON
      serializer = LibroSerializer(libros, many=True)
      return Response(serializer.data)

  elif request.method == 'POST':
      # Deserializar los datos recibidos en la petición
      serializer = LibroSerializer(data=request.data)
      if serializer.is_valid():
          serializer.save()  # Guardar el nuevo libro en la base de datos
          return Response(serializer.data, status=201)
      return Response(serializer.errors, status=400)  # Responder con errores de validación

# Vista para obtener, actualizar o eliminar un libro específico
@api_view(['GET', 'PUT', 'DELETE'])
def libro_detail(request, pk):
  try:
      # Buscar el libro por su clave primaria (pk)
      libro = Libro.objects.get(pk=pk)
  except Libro.DoesNotExist:
      return Response({'detail': 'Not found'}, status=404)  # Devolver error si no existe

  if request.method == 'GET':
      # Serializar y devolver los datos del libro solicitado
      serializer = LibroSerializer(libro)
      return Response(serializer.data)

  elif request.method == 'PUT':
      # Actualizar los datos del libro con la nueva información proporcionada
      serializer = LibroSerializer(libro, data=request.data)
      if serializer.is_valid():
          serializer.save()  # Guardar los cambios en la base de datos
          return Response(serializer.data)
      return Response(serializer.errors, status=400)  # Responder con errores de validación

  elif request.method == 'DELETE':
      # Eliminar el libro de la base de datos
      libro.delete()
      return Response(status=204)  # Responder con éxito sin contenido
  Explicación

  • libro_list maneja las solicitudes GET para obtener todos los libros y POST para crear un nuevo libro.
  • libro_detail maneja las solicitudes GET para obtener un libro por su pk, PUT para actualizar un libro y DELETE para eliminar un libro.
  • viewsets.ModelViewSet: Proporciona métodos predefinidos para manejar operaciones CRUD (Create, Read, Update, Delete).

Recuerda: En las vistas basadas en función, debes manejar manualmente las respuestas para cada tipo de solicitud HTTP.

8. Configuración de URLs

Para definir los endpoints de la API con vistas basadas en funciones, primero debemos configurar el archivo api/urls.py y luego registrarlo en config/urls.py.

1. Definir las rutas en api/urls.py

Abre api/urls.py y agrega lo siguiente:

python
from django.urls import path
from .views import libro_list, libro_detail

urlpatterns = [
  path('libros/', libro_list, name='libro-list'),  # Endpoint para listar y crear libros
  path('libros/<int:pk>/', libro_detail, name='libro-detail'),  # Endpoint para obtener, actualizar y eliminar un libro específico
]
2. Registrar las rutas en config/urls.py

Ahora, abre config/urls.py y agrega la referencia a api.urls:

python
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
  path('admin/', admin.site.urls),
  path('api/', include('api.urls')),  # Incluye las rutas de la aplicación `api`
]
  Resumen

Con esta configuración, los endpoints estarán disponibles en:
GET /api/libros/ → Listar libros
POST /api/libros/ → Crear un nuevo libro
GET /api/libros/<id>/ → Obtener detalles de un libro
PUT /api/libros/<id>/ → Actualizar un libro
DELETE /api/libros/<id>/ → Eliminar un libro

9. Configuración de Permisos y Autenticación

Para agregar autenticación básica, abre config/settings.py y configura el sistema de autenticación:

python
REST_FRAMEWORK = {
  'DEFAULT_PERMISSION_CLASSES': [
      'rest_framework.permissions.IsAuthenticated',
  ],
  'DEFAULT_AUTHENTICATION_CLASSES': [
      'rest_framework.authentication.SessionAuthentication',
      'rest_framework.authentication.BasicAuthentication',
  ]
}

10. Ejecutar Servidor de Desarrollo

bash
python manage.py runserver

11. Endpoints Disponibles

Ahora puedes acceder a tu API en http://127.0.0.1:8000/api/libros/. Esta ruta permitirá:

  Formularios y Manejo de Datos

  • GET /api/libros/: Listar libros
  • POST /api/libros/: Crear libro
  • GET /api/libros/{id}/: Detalle de libro
  • PUT /api/libros/{id}/: Actualizar libro
  • DELETE /api/libros/{id}/: Eliminar libro

12. Crear un Superusuario

Si no tienes un superusuario para acceder al panel de administración de Django, crea uno:

bash
python manage.py createsuperuser

Sigue las instrucciones para configurar un nombre de usuario, correo electrónico y contraseña. Accede al panel de administración en http://127.0.0.1:8000/admin/ con las credenciales creadas.