Sistema de gestión académica universitaria desarrollado con Django REST Framework y PostgreSQL. Este proyecto proporciona una API REST completa para administrar la estructura organizacional de una universidad, incluyendo facultades, carreras, materias, estudiantes y personal académico.
- Características
- Arquitectura
- Tecnologías
- Estructura del Proyecto
- Modelos de Datos
- Instalación y Ejecución
- API Endpoints
- Testing
- Funcionalidades Especiales
- Configuración
- API RESTful completa para gestión académica universitaria
- Arquitectura en capas (Models, Repositories, Services, Views)
- Generación de certificados en múltiples formatos (PDF, ODT, DOCX)
- Base de datos PostgreSQL con relaciones complejas
- Testing completo con fixtures y casos de prueba
- Dockerización para fácil despliegue
- Validaciones personalizadas con Django validators
- Paginación automática de resultados
- Soporte de internacionalización (Español - Argentina)
El proyecto sigue una arquitectura en capas que separa responsabilidades:
┌─────────────────┐
│ Views │ ← Capa de Presentación (API REST)
│ (ViewSets) │
└────────┬────────┘
│
┌────────▼────────┐
│ Serializers │ ← Validación y Serialización
└────────┬────────┘
│
┌────────▼────────┐
│ Services │ ← Lógica de Negocio
└────────┬────────┘
│
┌────────▼────────┐
│ Repositories │ ← Acceso a Datos
└────────┬────────┘
│
┌────────▼────────┐
│ Models │ ← Capa de Datos (ORM)
└─────────────────┘
- Models (
app/models/): Define la estructura de datos con Django ORM - Repositories (
app/repositories/): Maneja las operaciones CRUD sobre los modelos - Services (
app/services/): Implementa la lógica de negocio - Serializers (
app/serializers/): Valida y transforma datos para la API - Views (
app/views/): Expone endpoints REST usando ViewSets de DRF
- Django 5.2.7 - Framework web de alto nivel
- Django REST Framework 3.15.2 - Construcción de APIs REST
- PostgreSQL - Base de datos relacional
- psycopg2 2.9.10 - Adaptador PostgreSQL para Python
- python-dotenv - Gestión de variables de entorno
- hashids - Generación de IDs ofuscados
- weasyprint - Generación de PDFs
- python-odt-template - Generación de documentos ODT
- docxtpl - Generación de documentos DOCX
- Docker & Docker Compose - Contenedorización
- Python 3.12 - Lenguaje de programación
project-SysAcad/
├── app/ # Aplicación principal
│ ├── models/ # Modelos de datos (18 entidades)
│ │ ├── university.py # Universidad
│ │ ├── faculty.py # Facultad
│ │ ├── specialty.py # Especialidad/Carrera
│ │ ├── student.py # Estudiante
│ │ ├── subject.py # Materia
│ │ ├── plan.py # Plan de estudio
│ │ ├── authority.py # Autoridades
│ │ ├── position.py # Cargos
│ │ └── ... # Otros modelos
│ ├── repositories/ # Capa de acceso a datos
│ ├── services/ # Lógica de negocio
│ │ ├── certificate.py # Generación de certificados
│ │ └── ... # Servicios por entidad
│ ├── serializers/ # Serialización de datos
│ ├── views/ # ViewSets de la API
│ ├── validators/ # Validadores personalizados
│ ├── static/ # Archivos estáticos
│ ├── template/ # Templates para documentos
│ │ └── certificado/ # Templates de certificados
│ ├── config/ # Configuración de la app
│ ├── urls.py # Rutas de la API
│ └── admin.py # Configuración admin
├── main/ # Configuración Django
│ ├── settings.py # Configuración principal
│ ├── urls.py # URLs del proyecto
│ └── wsgi.py # WSGI application
├── tests/ # Suite de pruebas
│ ├── fixtures.py # Datos de prueba
│ └── test_*.py # Tests por entidad
├── docs/ # Documentación
│ └── class_diagram.puml # Diagrama de clases
├── docker-compose.yml # Orquestación de contenedores
├── Dockerfile # Imagen Docker
├── requirements.txt # Dependencias Python
├── manage.py # CLI de Django
└── README.md # Este archivo
El sistema cuenta con 18 modelos principales que representan la estructura universitaria:
- University: Universidad (nombre, acrónimo)
- Faculty: Facultad (datos de contacto, ubicación)
- Department: Departamento académico
- Area: Área de conocimiento
- Specialty: Especialidad/Carrera (asociada a faculty)
- SpecialtyType: Tipo de speciality
- Plan: Plan de estudios (vigencia)
- Subject: Materia (código único, nombre)
- Orientation: Orientación académica
- Degree: Título/Grado otorgado
- Group: Grupo de materias
- Student: Estudiante
- Datos personales (nombre, apellido, DNI)
- Fecha de nacimiento y género
- Número de legajo único
- Fecha de inscripción
- Relación con especialidad y tipo de documento
- Propiedades calculadas:
full_name,age
- Authority: Autoridades académicas
- Position: Cargos/Posiciones
- PositionCategory: Categoría de position
- DedicationType: Tipo de dedicación
- DocumentType: Tipos de documentos de identidad
University (1) ──→ (N) Faculty
Faculty (1) ──→ (N) Specialty
Specialty (1) ──→ (N) Student
Student (N) ──→ (1) DocumentType
- Python 3.12+ (para ejecución local)
- PostgreSQL 13+ (para ejecución local)
- Docker y Docker Compose (para ejecución con Docker)
- Git
git clone https://github.com/Zapallo-Code/project-SysAcad.git
cd project-SysAcadpython -m venv .venv
source .venv/bin/activate # En Linux/Mac
# o
.venv\Scripts\activate # En Windowspip install -r requirements.txtCrear un archivo .env en la raíz del proyecto:
# Django
SECRET_KEY=tu-secret-key-super-segura
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
# PostgreSQL
POSTGRES_DB=sysacad
POSTGRES_USER=postgres
POSTGRES_PASSWORD=tu-password
DATABASE_HOST=localhost
DATABASE_PORT=5432Crear la base de datos:
# Conectarse a PostgreSQL
psql -U postgres
# Crear la base de datos
CREATE DATABASE sysacad;
\qpython manage.py makemigrations
python manage.py migratepython manage.py createsuperuserpython manage.py runserverEl servidor estará disponible en: http://localhost:8000
Docker simplifica el despliegue al encapsular todas las dependencias.
git clone https://github.com/Zapallo-Code/project-SysAcad.git
cd project-SysAcadCrear archivo .env:
# Django
SECRET_KEY=tu-secret-key-super-segura
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1,backend
# PostgreSQL
POSTGRES_DB=sysacad
POSTGRES_USER=postgres
POSTGRES_PASSWORD=tu-password-seguro
DATABASE_HOST=db
DATABASE_PORT=5432DATABASE_HOST debe ser db (nombre del servicio).
docker-compose up --buildO en modo detached (segundo plano):
docker-compose up -d --builddocker-compose exec backend python manage.py makemigrations
docker-compose exec backend python manage.py migratedocker-compose exec backend python manage.py createsuperuser- API:
http://localhost:8000 - Admin:
http://localhost:8000/admin - PostgreSQL:
localhost:5432
# Ver logs
docker-compose logs -f backend
# Detener contenedores
docker-compose down
# Detener y eliminar volúmenes (⚠️ borra la BD)
docker-compose down -v
# Reconstruir sin cache
docker-compose build --no-cache
# Ejecutar comandos en el contenedor
docker-compose exec backend python manage.py <comando>
# Ejecutar tests
docker-compose exec backend python manage.py testLa API REST está disponible en /api/v1/ con los siguientes recursos:
| Recurso | Endpoint | Métodos |
|---|---|---|
| Universidades | /api/v1/university/ |
GET, POST, PUT, DELETE |
| Facultades | /api/v1/faculty/ |
GET, POST, PUT, DELETE |
| Especialidades | /api/v1/speciality/ |
GET, POST, PUT, DELETE |
| Estudiantes | /api/v1/student/ |
GET, POST, PUT, DELETE |
| Materias | /api/v1/subject/ |
GET, POST, PUT, DELETE |
| Planes | /api/v1/plan/ |
GET, POST, PUT, DELETE |
| Autoridades | /api/v1/authority/ |
GET, POST, PUT, DELETE |
| Cargos | /api/v1/position/ |
GET, POST, PUT, DELETE |
| Categorías Cargo | /api/v1/position_category/ |
GET, POST, PUT, DELETE |
| Departamentos | /api/v1/departament/ |
GET, POST, PUT, DELETE |
| Áreas | /api/v1/area/ |
GET, POST, PUT, DELETE |
| Grupos | /api/v1/group/ |
GET, POST, PUT, DELETE |
| Orientaciones | /api/v1/orientation/ |
GET, POST, PUT, DELETE |
| Títulos | /api/v1/degree/ |
GET, POST, PUT, DELETE |
| Tipos Dedicación | /api/v1/dedication_type/ |
GET, POST, PUT, DELETE |
| Tipos Documento | /api/v1/document_type/ |
GET, POST, PUT, DELETE |
| Tipos Especialidad | /api/v1/speciality_type/ |
GET, POST, PUT, DELETE |
curl -X GET http://localhost:8000/api/v1/student/curl -X GET http://localhost:8000/api/v1/student/1/curl -X POST http://localhost:8000/api/v1/student/ \
-H "Content-Type: application/json" \
-d '{
"first_name": "Juan",
"last_name": "Pérez",
"document_number": "12345678",
"document_type": 1,
"birth_date": "2000-01-01",
"gender": "M",
"student_number": 123456,
"enrollment_date": "2020-03-01",
"specialty": 1
}'curl -X PUT http://localhost:8000/api/v1/student/1/ \
-H "Content-Type: application/json" \
-d '{
"first_name": "Juan Modificado",
...
}'curl -X DELETE http://localhost:8000/api/v1/student/1/La API implementa paginación automática (100 elementos por página):
curl -X GET "http://localhost:8000/api/v1/student/?page=2"El proyecto incluye una suite completa de tests unitarios usando Django TestCase.
# Local
python manage.py test
# Docker
docker-compose exec backend python manage.py test# Test de un módulo específico
python manage.py test tests.test_student
# Test de una clase específica
python manage.py test tests.test_student.StudentTestCase
# Test de un método específico
python manage.py test tests.test_student.StudentTestCase.test_crearLos tests están organizados en tests/:
fixtures.py: Funciones auxiliares para crear datos de pruebatest_student.py: Tests para el modelo Studenttest_university.py: Tests para el modelo Universitytest_faculty.py: Tests para el modelo Faculty- ... (un archivo por cada modelo)
class StudentTestCase(TestCase):
def test_crear(self):
student = new_student()
self.assertIsNotNone(student)
self.assertEqual(student.last_name, "Pérez")
def test_find_by_id(self):
student = new_student()
r = StudentService.find_by_id(student.id)
self.assertIsNotNone(r)
self.assertEqual(r.first_name, "Juan")Los tests cubren:
- ✅ Creación de entidades
- ✅ Lectura por ID
- ✅ Listado completo
- ✅ Actualización de datos
- ✅ Eliminación lógica
- ✅ Validaciones de campos
- ✅ Relaciones entre entidades
El sistema puede generar certificados académicos en múltiples formatos:
- PDF (usando WeasyPrint)
- ODT (LibreOffice)
- DOCX (Microsoft Word)
# En app/services/student.py
def generar_certificado_student_regular(id: int, tipo: str) -> BytesIO:
# tipo puede ser: 'pdf', 'odt', 'docx'
student = StudentRepository.find_by_id(id)
context = self.__get_student_data(student)
documento = get_document_type(tipo)
return documento.generar(
folder='certificado',
template='certificado_pdf',
context=context
)Los templates están en app/template/certificado/:
certificado_pdf.html(para PDF)certificado_pdf.odt(para ODT)certificado_pdf.docx(para DOCX)
Varios modelos incluyen propiedades calculadas dinámicamente:
# Student
@property
def full_name(self):
return f"{self.first_name} {self.last_name}"
@property
def age(self):
today = date.today()
return today.year - self.birth_date.year - (
(today.month, today.day) < (self.birth_date.month, self.birth_date.day)
)
# Plan
@property
def is_active(self):
today = date.today()
return self.start_date <= today <= self.end_date| Variable | Descripción | Default |
|---|---|---|
SECRET_KEY |
Clave secreta de Django | - |
DEBUG |
Modo debug | True |
ALLOWED_HOSTS |
Hosts permitidos | localhost,127.0.0.1 |
POSTGRES_DB |
Nombre de la BD | sysacad |
POSTGRES_USER |
Usuario PostgreSQL | postgres |
POSTGRES_PASSWORD |
Contraseña PostgreSQL | postgres |
DATABASE_HOST |
Host de la BD | localhost / db |
DATABASE_PORT |
Puerto de la BD | 5432 |
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100,
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
],
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
],
}LANGUAGE_CODE = 'es-ar'
TIME_ZONE = 'America/Argentina/Buenos_Aires'
USE_I18N = True
USE_TZ = TrueAccede al panel de administración en /admin/ después de crear un superusuario.
Después de modificar modelos:
python manage.py makemigrations
python manage.py migratePara experimentar con los modelos:
python manage.py shell
# Ejemplo
>>> from app.models import Student
>>> Student.objects.all()- Fork el proyecto
- Crea una rama para tu feature (
git checkout -b feature/AmazingFeature) - Commit tus cambios (
git commit -m 'Add some AmazingFeature') - Push a la rama (
git push origin feature/AmazingFeature) - Abre un Pull Request
Este proyecto es parte de un trabajo académico universitario.
Proyecto SysAcad - Sistema Académico Universitario
Repository: https://github.com/Zapallo-Code/project-SysAcad
-
Valentin Rubio
-
Luciano Castro
-
Santiago Calzonari
-
Santiago Oses
-
Pablo Geyer