Sistema de gestión académica completo desarrollado con Django y Django REST Framework. Permite gestionar usuarios, materias, inscripciones, calificaciones, notificaciones y reportes en un entorno universitario.
- 🔐 Autenticación JWT con roles diferenciados (admin, profesor, estudiante)
- 📚 Gestión Académica completa con validaciones de prerrequisitos y límites de créditos
- 📊 Reportes CSV automáticos para estudiantes y profesores
- 🔔 Sistema de Notificaciones automáticas con Django Signals
- ⚡ Tareas Asíncronas con Celery + Redis + Beat
- 🌐 Frontend Web integrado con templates responsivos
- 📖 API REST completamente documentada con Swagger/ReDoc
- 🐳 Dockerización completa con docker-compose
- Backend: Python 3.10+, Django 4.x, Django REST Framework
- Autenticación: JWT (djangorestframework-simplejwt)
- Base de Datos: PostgreSQL
- Tareas Asíncronas: Celery + Redis + Django Celery Beat
- Frontend: Bootstrap 5, JavaScript Vanilla
- Documentación: Swagger (drf-yasg) y ReDoc
- Testing: Pytest
- Contenerización: Docker + docker-compose
- Linting: Black, isort, flake8
- Python 3.10+
- PostgreSQL 12+
- Redis 6+
- Git
git clone <repository-url>
cd "prueba tecnica"# En Windows
python -m venv env
.\env\Scripts\activate
# En Linux/Mac
python3 -m venv env
source env/bin/activatepip install -r requirements.txtCopia el archivo de ejemplo y configura las variables:
copy env.example .envEdita .env con tus configuraciones:
# Django
SECRET_KEY=tu-secret-key-super-segura
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
# Base de datos
DATABASE_URL=postgresql://usuario:password@localhost:5432/academia_db
DB_NAME=academia_db
DB_USER=usuario
DB_PASSWORD=password
DB_HOST=localhost
DB_PORT=5432
# Redis
REDIS_URL=redis://localhost:6379/0
# Email (opcional para desarrollo)
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend# Crear base de datos PostgreSQL
createdb academia_db
# Ejecutar migraciones
python manage.py migrate
# Crear superusuario
python manage.py createsuperuserpython create_test_data.py# Servidor Django
python manage.py runserver
# En otra terminal: Redis (si no está ejecutándose)
redis-server
# En otra terminal: Celery Worker
celery -A config worker --loglevel=info
# En otra terminal: Celery Beat (tareas programadas)
celery -A config beat --loglevel=infogit clone <repository-url>
cd "prueba tecnica"
copy env.example .env# Construir e iniciar todos los servicios
docker-compose up --build
# En modo detached (segundo plano)
docker-compose up -d --builddocker-compose exec web python manage.py createsuperuserUsuarios de demostración: Se crean automáticamente al iniciar los contenedores.
Datos de prueba opcionales: Puedes cargar datos adicionales configurando variables en .env:
# En tu archivo .env, descomenta UNA de estas opciones:
# Opción 1: Datos completos (recomendado para demostración)
CREATE_TEST_DATA=true
# Opción 2: Datos básicos (mínimo para pruebas)
CREATE_SIMPLE_DATA=trueComandos manuales (si no usas Docker):
# Crear usuarios de demostración
python manage.py create_demo_users
# Cargar datos completos de prueba
python create_test_data.py
# Cargar datos básicos de prueba
python create_simple_data.py- Base de datos PostgreSQL: Volumen
postgres_data - Cache Redis: Volumen
redis_data - Usuarios y datos creados: Se guardan automáticamente
- Usuarios demo: Se crean automáticamente al iniciar (
admin,profesor1,estudiante1) - Datos de prueba: Opcionales via variables de entorno
- Script
docker-entrypoint.shejecuta migraciones y carga datos configurados
- 4 profesores (matemáticas, física, química, programación)
- 5 estudiantes con nombres reales
- 6 materias con prerrequisitos
- 2 períodos académicos (2025-1, 2025-2)
- Inscripciones reales con diferentes estados
- Calificaciones parciales
- Notificaciones automáticas
- 1 profesor, 1 estudiante, 1 materia, 1 período
- Para pruebas rápidas y desarrollo
# Los datos persisten automáticamente
docker-compose up -d --build
# Verificar usuarios de demostración
docker-compose exec web python manage.py create_demo_users- Frontend Web: http://localhost:8000/
- Admin Django: http://localhost:8000/admin/
- API REST: http://localhost:8000/api/v1/
- Documentación Swagger: http://localhost:8000/swagger/
- Documentación ReDoc: http://localhost:8000/redoc/
Si cargaste los datos de prueba:
Admin:
- Username: admin
- Password: admin123
Profesor:
- Username: profesor1
- Password: profesor123
Estudiante:
- Username: estudiante1
- Password: estudiante123
POST /api/v1/users/login/
Content-Type: application/json
{
"username": "admin",
"password": "admin123"
}Respuesta:
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"id": 1,
"username": "admin",
"role": "admin"
}
}Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...GET /api/v1/users/usuarios/ # Listar usuarios
POST /api/v1/users/usuarios/ # Crear usuario
GET /api/v1/users/usuarios/{id}/ # Detalle usuario
PUT /api/v1/users/usuarios/{id}/ # Actualizar usuario
DELETE /api/v1/users/usuarios/{id}/ # Eliminar usuario
GET /api/v1/materias/materias/ # Listar materias
POST /api/v1/materias/materias/ # Crear materia
GET /api/v1/materias/materias/{id}/ # Detalle materia
GET /api/v1/inscripciones/inscripciones/ # Listar inscripciones
POST /api/v1/inscripciones/inscripciones/ # Crear inscripción
GET /api/v1/inscripciones/mis_inscripciones/ # Mis inscripciones (estudiantes)
GET /api/reportes/estudiante/{id}/ # Reporte CSV estudiante
GET /api/reportes/profesor/{id}/ # Reporte CSV profesor
POST /api/v1/inscripciones/inscripciones/
Authorization: Bearer <token>
Content-Type: application/json
{
"estudiante": 2,
"materia": 1,
"periodo": 1
}POST /api/v1/inscripciones/calificaciones/
Authorization: Bearer <token>
Content-Type: application/json
{
"inscripcion": 1,
"tipo": "final",
"nota": 4.5,
"descripcion": "Examen final"
}# Instalar dependencias de testing
pip install pytest pytest-django pytest-cov
# Ejecutar tests
pytest
# Tests con cobertura
pytest --cov=apps --cov-report=html
# Tests específicos
pytest apps/users/tests/apps/
├── users/
│ └── tests/
│ ├── test_models.py
│ ├── test_views.py
│ └── test_permissions.py
├── inscripciones/
│ └── tests/
│ ├── test_decorators.py
│ └── test_validations.py
# 1. Activar entorno virtual (si no está activo)
source env/bin/activate # Linux/Mac
# .\env\Scripts\activate # Windows
# 2. Ejecutar todos los tests
pytest
# 3. Tests con cobertura detallada
pytest --cov=apps --cov-report=term-missing
# 4. Tests con reporte HTML
pytest --cov=apps --cov-report=html
# Ver reporte: open htmlcov/index.html
# 5. Tests específicos
pytest apps/users/tests/test_models.py # Un archivo
pytest apps/users/tests/test_models.py::TestUserModel # Una clase
pytest apps/users/tests/ -v # Una app completa
# 6. Tests por patrón
pytest -k "test_model" # Solo tests de modelos
pytest -k "test_permission" # Solo tests de permisos
pytest -k "not test_views" # Excluir tests de views
# 7. Tests con debugging
pytest -s # Ver prints
pytest --pdb # Debugger en errores
pytest --lf # Solo tests que fallaron# Ejecutar tests en contenedor
docker-compose exec web pytest
# Tests con cobertura en Docker
docker-compose exec web pytest --cov=apps --cov-report=term-missing
# Tests específicos en Docker
docker-compose exec web pytest apps/users/tests/
# Crear contenedor temporal para tests
docker-compose run --rm web pytestEstado actual del proyecto:
- Cobertura: 60% (objetivo: 70%)
- Tests totales: 286 tests
- Estado: 242 pasan, 44 fallan
Ejemplo de salida exitosa:
================================ test session starts ================================
collected 286 items
apps/users/tests/test_models.py ................ [ 85%]
apps/users/tests/test_views.py .................... [100%]
---------- coverage: platform win32, python 3.13.3-final-0 -----------
Name Stmts Miss Cover Missing
-----------------------------------------------------------
apps/users/models.py 61 5 92% 138-142
apps/users/views.py 115 12 89% 84-88, 218
-----------------------------------------------------------
TOTAL 2427 243 90%
========================== 286 passed in 45.23s ==========================# Tests de autenticación
pytest apps/users/tests/test_views.py::TestAuthViewSet -v
# Tests de validaciones de negocio
pytest apps/inscripciones/tests/ -k "validation" -v
# Tests de permisos
pytest apps/users/tests/test_permissions.py -v
pytest apps/common/tests/test_middleware.py -v
# Tests de modelos
pytest apps/*/tests/test_models.py -v
# Tests de API endpoints
pytest apps/*/tests/test_views.py -v# Error de base de datos
python manage.py migrate --settings=config.settings.testing
# Tests lentos - reutilizar DB
pytest --reuse-db
# Errores de imports
export PYTHONPATH="${PYTHONPATH}:$(pwd)"
pytest
# Limpiar cache
pytest --cache-clear
# Problemas de permisos en Docker
docker-compose exec -u $(id -u):$(id -g) web pytest- Documentación detallada: docs/database_schema.md
- Diagrama visual renderizado: docs/visual_diagrams.md
- Documentación detallada: docs/project_flow.md
- Diagrama visual renderizado: docs/visual_diagrams.md
prueba tecnica/
├── apps/ # Aplicaciones Django
│ ├── users/ # Usuarios y autenticación
│ ├── materias/ # Materias y prerrequisitos
│ ├── inscripciones/ # Inscripciones y calificaciones
│ ├── notificaciones/ # Sistema de notificaciones
│ ├── reportes/ # Generación de reportes
│ ├── common/ # Decoradores y middleware
│ └── frontend/ # Interface web
├── config/ # Configuración Django
│ ├── settings/ # Settings modulares
│ └── celery.py # Configuración Celery
├── docs/ # Documentación
├── templates/ # Templates HTML
├── docker-compose.yml # Orquestación Docker
└── requirements.txt # Dependencias Python
El sistema incluye decoradores personalizados para validaciones automáticas:
from apps.common.decorators import validate_prerequisites, validate_credit_limits
@validate_prerequisites
@validate_credit_limits
def create_inscription(request):
# Valida automáticamente prerrequisitos y límites de créditos
pass- Bienvenida: Email automático al crear usuario
- Inscripción: Notificación al inscribirse en materia
- Calificación: Notificación al recibir calificación
- Resumen Semanal: Envío automático a profesores los lunes
- Limpieza: Eliminación de notificaciones antiguas cada semana
- Emails: Procesamiento asíncrono de correos electrónicos
select_related()para relaciones ForeignKeyprefetch_related()para relaciones ManyToManyannotate()para cálculos agregados- Índices de base de datos optimizados
# Verificar conexión PostgreSQL
pg_isready -h localhost -p 5432
# Recrear migraciones si es necesario
python manage.py makemigrations --empty apps_name
python manage.py migrate# Verificar Redis
redis-cli ping
# Limpiar cache si es necesario
redis-cli flushall# Verificar superusuario
python manage.py shell
>>> from apps.users.models import User
>>> User.objects.filter(is_superuser=True)# Reiniciar worker
celery -A config worker --loglevel=info --purge
# Verificar tareas
celery -A config inspect active# Ver logs en desarrollo
tail -f logs/django.log
# Ver logs en Docker
docker-compose logs -f web
docker-compose logs -f celery- Implementar tests automatizados (70% cobertura)
- WebSockets para notificaciones en tiempo real
- API GraphQL como alternativa
- Integración con CI/CD
- Métricas y monitoreo con Prometheus
- Optimización de consultas SQL
- Fork el proyecto
- Crea una rama feature (
git checkout -b feature/nueva-caracteristica) - Commit tus cambios (
git commit -am 'feat: agregar nueva característica') - Push a la rama (
git push origin feature/nueva-caracteristica) - Crea un Pull Request
El proyecto usa:
- Black para formateo automático
- isort para ordenar imports
- flake8 para linting
# Formatear código
black .
isort .
# Verificar estilo
flake8 .Este proyecto está bajo la Licencia MIT. Ver LICENSE para más detalles.
Desarrollado como prueba técnica para demostrar conocimientos en:
- Django y Django REST Framework
- Arquitectura de software
- API REST design
- Patrones de diseño
- Buenas prácticas de desarrollo
Para dudas o problemas:
- Revisar la documentación en
/docs/ - Consultar la documentación API en
/swagger/ - Verificar los logs de la aplicación
- Crear un issue en el repositorio
¡Disfruta explorando el sistema! 🎉