Tutorial Django React: Construye una Aplicación Completa de Gestión de Tareas
En este tutorial detallado, dirigido a desarrolladores con conocimientos intermedios en Python y JavaScript, aprenderás a construir una aplicación completa para la gestión de tareas utilizando Django como backend y React como frontend. Cubriremos desde la configuración del entorno, creación de una API RESTful con Django REST Framework, desarrollo de la interfaz de usuario con React, integración entre frontend y backend mediante llamadas API, autenticación de usuarios, manejo de estados en React, hasta un despliegue básico.
Este tutorial está optimizado para SEO incluyendo términos clave como: tutorial Django React, aplicación gestión tareas, API REST Django, y desarrollo full-stack Python JavaScript.
Tabla de Contenidos
- Configuración del Entorno
- Creación de la API RESTful con Django REST Framework
- Desarrollo de la Interfaz de Usuario con React
- Integración Frontend y Backend con APIs
- Implementación de Autenticación de Usuarios
- Manejo de Estado en React para Gestión de Tareas
- Despliegue Básico de la Aplicación
- Conclusión y Buenas Prácticas
Configuración del Entorno
Empezamos preparando nuestro entorno para desarrollo full-stack con Django y React.
1. Crear un entorno virtual para Python
Abre tu terminal y ejecuta:
1 2 3 4 |
python3 -m venv env env/bin/activate # en Linux/macOS env\Scripts\activate # en Windows |
2. Instalar Django y Django REST Framework
1 2 |
pip install django djangorestframework djangorestframework-simplejwt corsheaders |
3. Crear el proyecto Django
1 2 3 |
django-admin startproject tareas_backend cd tareas_backend |
4. Crear una app Django para la API
1 2 |
python manage.py startapp api |
5. Configura React usando create-react-app
En otra terminal, en la carpeta superior:
1 2 3 |
npx create-react-app tareas_frontend cd tareas_frontend |
Recomendaciones
- Asegúrate de tener Node.js v14+ instalado.
- Instala Postman o usa herramientas similares para probar la API.
Creación de la API RESTful con Django REST Framework
1. Configura settings.py
Agrega las apps instaladas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
INSTALLED_APPS = [ ... 'rest_framework', 'corsheaders', 'api', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ... ] # Configura CORS para desarrollo CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", ] # Configura autenticación JWT REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), } |
2. Define el modelo Task
En api/models.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from django.db import models from django.contrib.auth.models import User class Task(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='tasks') title = models.CharField(max_length=255) description = models.TextField(blank=True) completed = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title |
3. Migraciones
1 2 3 |
python manage.py makemigrations python manage.py migrate |
4. Serializadores
En api/serializers.py
:
1 2 3 4 5 6 7 8 |
from rest_framework import serializers from .models import Task class TaskSerializer(serializers.ModelSerializer): class Meta: model = Task fields = ['id', 'title', 'description', 'completed', 'created_at'] |
5. Vistas y URLs
En api/views.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from rest_framework import viewsets, permissions from .models import Task from .serializers import TaskSerializer class TaskViewSet(viewsets.ModelViewSet): serializer_class = TaskSerializer permission_classes = [permissions.IsAuthenticated] def get_queryset(self): return Task.objects.filter(user=self.request.user).order_by('-created_at') def perform_create(self, serializer): serializer.save(user=self.request.user) |
Configura URLs en api/urls.py
:
1 2 3 4 5 6 7 8 9 10 11 |
from rest_framework.routers import DefaultRouter from django.urls import path, include from .views import TaskViewSet router = DefaultRouter() router.register('tasks', TaskViewSet, basename='tasks') urlpatterns = [ path('', include(router.urls)), ] |
En el archivo principal tareas_backend/urls.py
, agrega:
1 2 3 4 5 6 7 8 9 10 11 12 |
from django.contrib import admin from django.urls import path, include from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('api.urls')), # Endpoints de autenticación JWT path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), ] |
6. Crea un superusuario para pruebas
1 2 |
python manage.py createsuperuser |
7. Ejecuta el servidor Django
1 2 |
python manage.py runserver |
Ya tienes lista la API REST Django para gestionar tareas con autenticación JWT.
Desarrollo de la Interfaz de Usuario con React
1. Instala dependencias necesarias
1 2 |
npm install axios jwt-decode react-router-dom |
2. Estructura básica del proyecto
En src/
crea las carpetas:
components/
pages/
services/
3. Configuración del Router y autenticación
En src/App.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import React from 'react'; import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; import Login from './pages/Login'; import TaskManager from './pages/TaskManager'; function App() { const isAuthenticated = !!localStorage.getItem('access_token'); return ( <Router> <Routes> <Route path="/login" element={<Login />} /> <Route path="/" element={isAuthenticated ? <TaskManager /> : <Navigate to="/login" />} /> </Routes> </Router> ); } export default App; |
4. Crear página de Login
En src/pages/Login.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
import React, { useState } from 'react'; import axios from 'axios'; import { useNavigate } from 'react-router-dom'; function Login() { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(null); const navigate = useNavigate(); const handleSubmit = async (e) => { e.preventDefault(); try { const response = await axios.post('http://localhost:8000/api/token/', { username, password }); localStorage.setItem('access_token', response.data.access); localStorage.setItem('refresh_token', response.data.refresh); navigate('/'); } catch (err) { setError('Usuario o contraseña incorrectos'); } }; return ( <div> <h2>Iniciar Sesión</h2> <form onSubmit={handleSubmit}> <input type="text" placeholder="Usuario" value={username} onChange={(e) => setUsername(e.target.value)} required /> <input type="password" placeholder="Contraseña" value={password} onChange={(e) => setPassword(e.target.value)} required /> <button type="submit">Entrar</button> </form> {error && <p style={{color: 'red'}}>{error}</p>} </div> ); } export default Login; |
Integración Frontend y Backend con APIs
1. Servicio API con Axios
Crea src/services/api.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import axios from 'axios'; const api = axios.create({ baseURL: 'http://localhost:8000/api/', }); // Interceptor para incluir token JWT api.interceptors.request.use(config => { const token = localStorage.getItem('access_token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); export default api; |
2. Consumir la API en componentes
Por ejemplo, en src/pages/TaskManager.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
import React, { useEffect, useState } from 'react'; import api from '../services/api'; function TaskManager() { const [tasks, setTasks] = useState([]); const [title, setTitle] = useState(''); const [description, setDescription] = useState(''); useEffect(() => { fetchTasks(); }, []); const fetchTasks = async () => { try { const res = await api.get('tasks/'); setTasks(res.data); } catch (error) { console.error(error); } }; const addTask = async () => { if (!title) return; try { await api.post('tasks/', { title, description }); setTitle(''); setDescription(''); fetchTasks(); } catch (error) { console.error(error); } }; const toggleCompletion = async (task) => { try { await api.patch(`tasks/${task.id}/`, { completed: !task.completed }); fetchTasks(); } catch (error) { console.error(error); } }; const logout = () => { localStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); window.location.reload(); }; return ( <div> <h1>Gestión de Tareas</h1> <button onClick={logout}>Cerrar sesión</button> <div> <input type="text" placeholder="Título" value={title} onChange={(e) => setTitle(e.target.value)} /> <textarea placeholder="Descripción" value={description} onChange={(e) => setDescription(e.target.value)} /> <button onClick={addTask}>Agregar Tarea</button> </div> <ul> {tasks.map((task) => ( <li key={task.id}> <input type="checkbox" checked={task.completed} onChange={() => toggleCompletion(task)} /> <strong>{task.title}</strong>: {task.description} </li> ))} </ul> </div> ); } export default TaskManager; |
Implementación de Autenticación de Usuarios
Ya integramos autenticación JWT en Django y la consumimos en React para proteger la API y rutas.
Consejos para mejorar la autenticación
- Renovar tokens con
refresh_token
para no desconectar usuarios rápidamente. - Manejar expiración del token y redirigir al login.
- Añadir formularios de registro en backend y frontend para crear usuarios.
Manejo de Estado en React para Gestión de Tareas
En el ejemplo anterior usamos useState
y useEffect
para manejar el estado de tareas y formularios.
Para proyectos más grandes considera:
- Uso de Context API para compartir estado global (ej. usuario autenticado)
- Integrar librerías como Redux o Recoil para estados complejos
Ejemplo básico usando Context API para el token (opcional):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import React, { createContext, useState } from 'react'; export const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [token, setToken] = useState(localStorage.getItem('access_token')); const login = (token) => { setToken(token); localStorage.setItem('access_token', token); }; const logout = () => { setToken(null); localStorage.removeItem('access_token'); }; return ( <AuthContext.Provider value={{ token, login, logout }}> {children} </AuthContext.Provider> ); }; |
Y consumiendo en componentes para obtener el estado global.
Despliegue Básico de la Aplicación
1. Prepara backend para producción
- Usa un servidor WSGI como Gunicorn
- Configura variables de entorno y secretos
- Configura base de datos productiva (PostgreSQL, etc.)
Ejemplo básico ejecución:
1 2 |
gunicorn tareas_backend.wsgi |
2. Prepara frontend para producción
1 2 |
npm run build |
Puedes servir el resultado del build con Nginx o cualquier servidor estático.
3. Opciones de despliegue
- Plataforma VPS (DigitalOcean, AWS EC2)
- PaaS (Heroku, Railway)
- Servicios específicos para React (Netlify, Vercel)
Asegúrate de configurar correctamente los orígenes CORS entre frontend y backend para producción.
Conclusión y Buenas Prácticas
En este tutorial has aprendido a construir una aplicación gestión tareas usando Django REST Framework en el backend y React en el frontend, abordando temas clave en el desarrollo full-stack Python JavaScript.
Resumen de aprendizajes:
- Configuración completa del entorno para desarrollo Django y React
- Creación de API REST Django segura con autenticación JWT
- Desarrollo de UI React con manejo de estado y rutas protegidas
- Integración vía Axios para comunicación frontend-backend
- Consideraciones para el despliegue básico
Buenas prácticas recomendadas:
- Mantener tus dependencias actualizadas y usar entornos virtuales
- Modularizar tu código en frontend y backend
- Manejar errores y estados de carga en la UI
- Proteger las rutas y datos sensibles con autenticación y permisos
- Versionar tu código con Git y usar CI/CD para despliegues automatizados
Si deseas ampliar este proyecto, considera agregar:
- Registro y verificación de usuarios
- Roles y permisos avanzados
- Filtros y paginación en la API
- Tests automatizados para backend y frontend
¡Anímate a poner en práctica este tutorial Django React y lleva tus habilidades full-stack al siguiente nivel!
Si te ha gustado este contenido, no olvides compartirlo y suscribirte para más tutoriales de desarrollo modernos.