Tutorial completo para crear una aplicación web de encuestas con Django y React
En este tutorial encuestas Django React aprenderás a crear una app de encuestas fullstack utilizando Django para el backend y React para el frontend. Te guiaremos paso a paso en la configuración del proyecto, la creación de modelos, desarrollo de una API REST con Django REST Framework, consumo de la API desde React, manejo de estados y un despliegue básico. Este tutorial es ideal para desarrolladores con conocimientos intermedios que desean integrar frontend y backend modernos con un enfoque profesional y didáctico.
Índice
- 1. Configuración del proyecto Django
- 2. Creación de modelos para encuestas y respuestas
- 3. Desarrollo de una API REST con Django REST Framework
- 4. Configuración del proyecto React
- 5. Consumo de la API en React
- 6. Manejo de estados en React
- 7. Despliegue básico
- Conclusión y buenas prácticas
1. Configuración del proyecto Django
Paso 1. Crear y activar un entorno virtual
1 2 3 4 |
python -m venv env source env/bin/activate # Linux / macOS # .\env\Scripts\activate # Windows |
Paso 2. Instalar Django y Django REST Framework
1 2 |
pip install django djangorestframework |
Paso 3. Crear el proyecto Django
1 2 3 |
django-admin startproject encuesta_backend cd encuesta_backend |
Paso 4. Crear la aplicación “polls”
1 2 |
python manage.py startapp polls |
Paso 5. Registrar la app y REST Framework
Edita encuesta_backend/settings.py
:
1 2 3 4 5 6 |
INSTALLED_APPS = [ ... 'rest_framework', 'polls', ] |
2. Creación de modelos para encuestas y respuestas
Para una app de encuestas sencilla definiremos dos modelos:
Encuesta
(Poll) con un título y fechaOpcion
(Option) como respuestas posibles de la encuesta
Crear modelos en polls/models.py
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from django.db import models class Encuesta(models.Model): titulo = models.CharField(max_length=200) fecha_creacion = models.DateTimeField(auto_now_add=True) def __str__(self): return self.titulo class Opcion(models.Model): encuesta = models.ForeignKey(Encuesta, related_name='opciones', on_delete=models.CASCADE) texto = models.CharField(max_length=100) votos = models.PositiveIntegerField(default=0) def __str__(self): return self.texto |
Ejecutar migraciones
1 2 3 |
python manage.py makemigrations polls python manage.py migrate |
3. Desarrollo de una API REST con Django REST Framework
Para exponer las encuestas y respuestas a React tendremos una API REST.
Paso 1. Crear serializers en polls/serializers.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from rest_framework import serializers from .models import Encuesta, Opcion class OpcionSerializer(serializers.ModelSerializer): class Meta: model = Opcion fields = ['id', 'texto', 'votos'] class EncuestaSerializer(serializers.ModelSerializer): opciones = OpcionSerializer(many=True) class Meta: model = Encuesta fields = ['id', 'titulo', 'fecha_creacion', 'opciones'] def create(self, validated_data): opciones_data = validated_data.pop('opciones') encuesta = Encuesta.objects.create(**validated_data) for opcion_data in opciones_data: Opcion.objects.create(encuesta=encuesta, **opcion_data) return encuesta |
Paso 2. Crear vistas con viewsets en polls/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from rest_framework import viewsets from .models import Encuesta, Opcion from .serializers import EncuestaSerializer, OpcionSerializer from rest_framework.decorators import action from rest_framework.response import Response from rest_framework import status class EncuestaViewSet(viewsets.ModelViewSet): queryset = Encuesta.objects.all() serializer_class = EncuestaSerializer @action(detail=True, methods=['post']) def votar(self, request, pk=None): encuesta = self.get_object() opcion_id = request.data.get('opcion_id') try: opcion = encuesta.opciones.get(pk=opcion_id) opcion.votos += 1 opcion.save() return Response({'status': 'voto registrado'}) except Opcion.DoesNotExist: return Response({'error': 'opcion no encontrada'}, status=status.HTTP_404_NOT_FOUND) |
Paso 3. Configurar rutas en polls/urls.py
1 2 3 4 5 6 7 8 9 |
from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import EncuestaViewSet router = DefaultRouter() router.register(r'encuestas', EncuestaViewSet) urlpatterns = [ path('', include(router.urls)), ] |
Paso 4. Añadir rutas al proyecto principal encuesta_backend/urls.py
1 2 3 4 5 6 7 |
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('polls.urls')), ] |
Paso 5. Correr servidor Django
1 2 |
python manage.py runserver |
Puedes probar la API en http://127.0.0.1:8000/api/encuestas/
.
4. Configuración del proyecto React
Paso 1. Crear proyecto React usando Create React App
En una terminal nueva, en la carpeta padre:
1 2 3 |
npx create-react-app encuesta_frontend cd encuesta_frontend |
Paso 2. Instalar Axios para llamadas HTTP
1 2 |
npm install axios |
Paso 3. Estructura base del proyecto
Organiza la carpeta src
con:
components/
(para componentes React)api.js
(configuración de llamadas API)
5. Consumo de la API en React
Paso 1. Configuración inicial src/api.js
1 2 3 4 5 6 |
import axios from 'axios'; const api = axios.create({ baseURL: 'http://127.0.0.1:8000/api/', }); export default api; |
Paso 2. Crear componente EncuestaList.js
para mostrar encuestas
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 |
import React, { useEffect, useState } from 'react'; import api from '../api'; function EncuestaList() { const [encuestas, setEncuestas] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { api.get('encuestas/') .then(response => { setEncuestas(response.data); setLoading(false); }) .catch(e => { setError('Error al cargar encuestas.'); setLoading(false); }); }, []); if (loading) return <p>Cargando encuestas...</p>; if (error) return <p>{error}</p>; return ( <div> <h2>Encuestas</h2> {encuestas.map(encuesta => ( <EncuestaItem key={encuesta.id} encuesta={encuesta} /> ))} </div> ); } // Componente para mostrar opción y votar function EncuestaItem({ encuesta }) { const [selectedOpcion, setSelectedOpcion] = useState(null); const [mensaje, setMensaje] = useState(''); const votar = () => { if (selectedOpcion === null) { setMensaje('Selecciona una opción para votar.'); return; } api.post(`encuestas/${encuesta.id}/votar/`, { opcion_id: selectedOpcion }) .then(() => { setMensaje('Gracias por votar.'); }) .catch(() => { setMensaje('Error al registrar el voto.'); }); }; return ( <div style={{border: "1px solid #ccc", margin: "10px", padding: "10px"}}> <h3>{encuesta.titulo}</h3> <ul> {encuesta.opciones.map((opcion) => ( <li key={opcion.id}> <label> <input type="radio" name={`opcion-${encuesta.id}`} value={opcion.id} onChange={() => setSelectedOpcion(opcion.id)} /> {opcion.texto} - Votos: {opcion.votos} </label> </li> ))} </ul> <button onClick={votar}>Votar</button> {mensaje && <p>{mensaje}</p>} </div> ); } export default EncuestaList; |
Paso 3. Usar el componente en src/App.js
1 2 3 4 5 6 7 8 9 10 11 12 |
import React from 'react'; import EncuestaList from './components/EncuestaList'; function App() { return ( <div className="App"> <h1>Aplicación de Encuestas Fullstack</h1> <EncuestaList /> </div> ); } export default App; |
Paso 4. Ejecutar React
1 2 |
npm start |
Abre http://localhost:3000
en el navegador.
6. Manejo de estados en React
En el código anterior manejamos estados con useState
para:
- Listado de encuestas
- Opción seleccionada
- Mensajes de estado (cargando, error, éxito)
También usamosuseEffect
para cargar la lista de encuestas al montar el componente.
Para proyectos más grandes, considera usar Context API o librerías como Redux para manejar estados globales.
7. Despliegue básico
Opciones para desplegar la app fullstack:
- Desplegar backend Django con servicios como Heroku, Railway o render.com
- Desplegar frontend React en servicios de hosting estático como Netlify o Vercel
Recomendaciones:
- Usa
django-cors-headers
para manejar CORS si frontend y backend corren en dominios distintos.
Instalación y configuración mínima:
1 2 |
pip install django-cors-headers |
En settings.py
:
1 2 3 4 5 6 7 |
INSTALLED_APPS += ['corsheaders'] MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware'] + MIDDLEWARE CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "https://tudominiofrontend.com", ] |
- Para producción compila React con
npm run build
y sirve la carpetabuild
vía servidor web o integrándola en Django condjango-webpack-loader
o simplificando con nginx.
Conclusión y buenas prácticas
Has completado el Django REST React tutorial para crear una aplicación de encuestas fullstack que consume una API REST desde un frontend React. Estos son puntos clave para consolidar:
- Mantén modelos y serializers bien estructurados para facilitar mantenimiento.
- Usa viewsets y routers para acelerar el desarrollo de APIs REST.
- Gestiona estados en React racionalmente con
useState
yuseEffect
para datos asincrónicos. - Implementa manejo de errores robusto tanto en backend como en frontend para mejorar la experiencia del usuario.
- Configura CORS correctamente para evitar problemas de seguridad.
Invitamos a continuar explorando: - Añadir autenticación y autorización (Django Token Auth + React context)
- Manejar formularios avanzados para crear encuestas dinámicamente desde el frontend
- Optimizar el despliegue con contenedores Docker
Si te gustó este tutorial, ¡comparte y suscríbete para más contenido de desarrollo web fullstack Python JavaScript!