From f2ec9db736246a19fe175b2aa2d3ec3a45a699a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Ram=C3=ADrez=20de=20la=20Corte?= Date: Wed, 11 Feb 2026 13:01:25 +0100 Subject: [PATCH 1/6] refactor: replace django-rest-swagger with drf-spectacular --- decide/decide/settings.py | 12 ++++++++++-- decide/decide/urls.py | 8 +++----- requirements.txt | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/decide/decide/settings.py b/decide/decide/settings.py index 1d22b6732..c33350931 100644 --- a/decide/decide/settings.py +++ b/decide/decide/settings.py @@ -42,7 +42,7 @@ 'django_filters', 'rest_framework', 'rest_framework.authtoken', - 'rest_framework_swagger', + 'drf_spectacular', 'gateway', ] @@ -51,7 +51,15 @@ 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.TokenAuthentication', ), - 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning' + 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning', + 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', +} + +SPECTACULAR_SETTINGS = { + 'TITLE': 'Decide API', + 'DESCRIPTION': 'Plataforma de voto electrónico educativa', + 'VERSION': '1.0.0', + 'SERVE_INCLUDE_SCHEMA': False, } AUTHENTICATION_BACKENDS = [ diff --git a/decide/decide/urls.py b/decide/decide/urls.py index d73f3cdb5..79237bbf2 100644 --- a/decide/decide/urls.py +++ b/decide/decide/urls.py @@ -16,14 +16,12 @@ from django.conf import settings from django.contrib import admin from django.urls import path, include -from rest_framework_swagger.views import get_swagger_view - - -schema_view = get_swagger_view(title='Decide API') +from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView urlpatterns = [ path('admin/', admin.site.urls), - path('doc/', schema_view), + path('api/schema/', SpectacularAPIView.as_view(), name='schema'), + path('doc/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), path('gateway/', include('gateway.urls')), ] diff --git a/requirements.txt b/requirements.txt index 02390a41f..a4aac138d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,5 +8,5 @@ psycopg2==2.9.4 coverage==6.5.0 jsonnet==0.18.0 django-nose==1.4.6 -django-rest-swagger==2.2.0 +drf-spectacular==0.29.0 selenium==4.7.2 From 8a8720e978b34233ee55a98ba21e5c30cf503f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Ram=C3=ADrez=20de=20la=20Corte?= Date: Wed, 11 Feb 2026 13:11:59 +0100 Subject: [PATCH 2/6] chore: remove deprecated django-nose dependency --- decide/decide/settings.py | 2 -- requirements.txt | 1 - 2 files changed, 3 deletions(-) diff --git a/decide/decide/settings.py b/decide/decide/settings.py index c33350931..129caf94d 100644 --- a/decide/decide/settings.py +++ b/decide/decide/settings.py @@ -159,8 +159,6 @@ USE_TZ = True -TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ diff --git a/requirements.txt b/requirements.txt index a4aac138d..9cb365c1e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,5 @@ django-filter==22.1 psycopg2==2.9.4 coverage==6.5.0 jsonnet==0.18.0 -django-nose==1.4.6 drf-spectacular==0.29.0 selenium==4.7.2 From f192c955776230082fe673c69e93dc658c444279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Ram=C3=ADrez=20de=20la=20Corte?= Date: Wed, 11 Feb 2026 17:21:29 +0100 Subject: [PATCH 3/6] refactor: migration python 3.9 to python 3.12 --- .github/workflows/django.yml | 2 +- .travis.yml | 21 --------------------- README.md | 17 ++++++++++------- docker/Dockerfile | 9 +++------ 4 files changed, 14 insertions(+), 35 deletions(-) delete mode 100644 .travis.yml diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 3c445f943..b497bc581 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -10,7 +10,7 @@ jobs: build: strategy: matrix: - pyversion: ['3.8','3.9'] + pyversion: ['3.12'] runs-on: ubuntu-latest diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b72f88a6e..000000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -dist: xenial - -services: - - postgresql -addons: - postgresql: "9.4" -before_script: - - psql -U postgres -c "create user decide password 'decide'" - - psql -U postgres -c "create database test_decide owner decide" - - psql -U postgres -c "ALTER USER decide CREATEDB" -language: python -python: - - "3.6" -install: - - pip install -r requirements.txt - - pip install codacy-coverage -script: - - cd decide - - coverage run --branch --source=. ./manage.py test --keepdb --with-xunit - - coverage xml - - python-codacy-coverage -r coverage.xml diff --git a/README.md b/README.md index 7bd6302a0..f34b5f592 100644 --- a/README.md +++ b/README.md @@ -261,8 +261,12 @@ Lanzar una consola SQL: $ docker exec -ti decide_db ash -c "su - postgres -c 'psql postgres'" -Ejecutar con vagrant + ansible ------------------------------- +Ejecutar con vagrant + ansible (DEPRECATED) +-------------------------------------------- + +> **DEPRECATED:** La configuración de Vagrant usa `ubuntu/bionic64` (Ubuntu 18.04 EOL) con +> Python 3.6, que es incompatible con la versión actual del proyecto (Python 3.12+). +> Se recomienda usar Docker en su lugar. Existe una configuración de vagrant que crea una máquina virtual con todo lo necesario instalado y listo para funcionar. La configuración está en @@ -463,8 +467,8 @@ Si se quieren añadir más casuística a la carga inicial, basta con editar el " la misma estructura que los datos contenidos en el mismo. -Cabe añadir que previo a ejecutar ambos comandos, deberemos haber activado nuestro entorno de -Python 3.9. +Cabe añadir que previo a ejecutar ambos comandos, deberemos haber activado nuestro entorno de +Python 3.12. El archivo "populate.json" se ha generado manualmente con ayuda de la documentación encontrada en @@ -485,9 +489,8 @@ versiones usadas actualmente se corresponden a las siguientes: * psycopg2 = 2.9.4 * coverage = 6.5.0 * jsonnet = 0.18.0 -* django-nose = 1.4.6 -* django-rest-swagger = 2.2.0 -* Python = 3.9 +* drf-spectacular = 0.29.0 +* Python = 3.12 * Vue=3 * Bootstrap=5.2 * selenium = 4.7.2 diff --git a/docker/Dockerfile b/docker/Dockerfile index 1e119996c..e471d697a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,12 +1,9 @@ -from python:3.9-alpine +from python:3.12-alpine -RUN apk add --no-cache git postgresql-dev gcc libc-dev -RUN apk add --no-cache gcc g++ make libffi-dev python3-dev build-base +RUN apk add --no-cache postgresql-dev gcc libc-dev gcc g++ make libffi-dev python3-dev build-base RUN pip install gunicorn -RUN pip install psycopg2 -RUN pip install ipdb -RUN pip install ipython +RUN pip install --upgrade pip WORKDIR /app From fb7abc948d1aa062357ec40a4e315123cb204e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Ram=C3=ADrez=20de=20la=20Corte?= Date: Wed, 11 Feb 2026 18:11:09 +0100 Subject: [PATCH 4/6] BREAKING CHANGE: update dependencies. django 4.1 to django 5.2, postgres 11 to postgres 14 --- .github/workflows/django.yml | 2 +- ...2_alter_census_unique_together_and_more.py | 21 +++++++++++++++++++ decide/census/models.py | 4 +++- decide/decide/settings.py | 2 -- docker/docker-compose.yml | 4 ++-- requirements.txt | 18 ++++++++-------- 6 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 decide/census/migrations/0002_alter_census_unique_together_and_more.py diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index b497bc581..929035acd 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -16,7 +16,7 @@ jobs: services: postgres: - image: postgres:11.18-bullseye + image: postgres:14-bullseye env: POSTGRES_USER: decide POSTGRES_PASSWORD: decide diff --git a/decide/census/migrations/0002_alter_census_unique_together_and_more.py b/decide/census/migrations/0002_alter_census_unique_together_and_more.py new file mode 100644 index 000000000..ccbd9ff98 --- /dev/null +++ b/decide/census/migrations/0002_alter_census_unique_together_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 5.2 on 2026-02-11 17:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('census', '0001_initial'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='census', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='census', + constraint=models.UniqueConstraint(fields=('voting_id', 'voter_id'), name='unique_voting_voter'), + ), + ] diff --git a/decide/census/models.py b/decide/census/models.py index e51a5b44e..6d6ed06e0 100644 --- a/decide/census/models.py +++ b/decide/census/models.py @@ -6,4 +6,6 @@ class Census(models.Model): voter_id = models.PositiveIntegerField() class Meta: - unique_together = (('voting_id', 'voter_id'),) + constraints = [ + models.UniqueConstraint(fields=['voting_id', 'voter_id'], name='unique_voting_voter'), + ] diff --git a/decide/decide/settings.py b/decide/decide/settings.py index 129caf94d..1a1eab5e1 100644 --- a/decide/decide/settings.py +++ b/decide/decide/settings.py @@ -154,8 +154,6 @@ USE_I18N = True -USE_L10N = True - USE_TZ = True diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 50ff01798..867a1b90c 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -4,7 +4,7 @@ services: db: restart: always container_name: decide_db - image: postgres:11.18-bullseye + image: pgautoupgrade/pgautoupgrade:14-alpine3.21 volumes: - db:/var/lib/postgresql/data networks: @@ -16,7 +16,7 @@ services: container_name: decide_web image: decide_web:latest build: . - command: ash -c "python manage.py migrate && gunicorn -w 5 decide.wsgi --timeout=500 -b 0.0.0.0:5000" + command: ash -c "python manage.py collectstatic --noinput --clear && python manage.py migrate && gunicorn -w 5 decide.wsgi --timeout=500 -b 0.0.0.0:5000" expose: - "5000" volumes: diff --git a/requirements.txt b/requirements.txt index 9cb365c1e..b6c0e931c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,11 @@ -Django==4.1 +Django==5.2 pycryptodome==3.15.0 -djangorestframework==3.14.0 -django-cors-headers==3.13.0 -requests==2.28.1 -django-filter==22.1 -psycopg2==2.9.4 -coverage==6.5.0 -jsonnet==0.18.0 +djangorestframework==3.15.2 +django-cors-headers==4.6.0 +requests==2.32.3 +django-filter==24.3 +psycopg2==2.9.10 +coverage==7.6.10 +jsonnet==0.20.0 drf-spectacular==0.29.0 -selenium==4.7.2 +selenium==4.27.1 From 2d2e1773d9e178f61608133ac5a9c0894ca04055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Ram=C3=ADrez=20de=20la=20Corte?= Date: Wed, 11 Feb 2026 18:20:37 +0100 Subject: [PATCH 5/6] doc: update README.md --- README.md | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f34b5f592..c2807eb2c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.com/wadobo/decide.svg?branch=master)](https://travis-ci.com/wadobo/decide) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/6a6e89e141b14761a19288a6b28db474)](https://www.codacy.com/gh/decide-update-4-1/decide-update-4.1/dashboard?utm_source=github.com&utm_medium=referral&utm_content=decide-update-4-1/decide-update-4.1&utm_campaign=Badge_Grade) [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/6a6e89e141b14761a19288a6b28db474)](https://www.codacy.com/gh/decide-update-4-1/decide-update-4.1/dashboard?utm_source=github.com&utm_medium=referral&utm_content=decide-update-4-1/decide-update-4.1&utm_campaign=Badge_Coverage) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/6a6e89e141b14761a19288a6b28db474)](https://www.codacy.com/gh/decide-update-4-1/decide-update-4.1/dashboard?utm_source=github.com&utm_medium=referral&utm_content=decide-update-4-1/decide-update-4.1&utm_campaign=Badge_Grade) [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/6a6e89e141b14761a19288a6b28db474)](https://www.codacy.com/gh/decide-update-4-1/decide-update-4.1/dashboard?utm_source=github.com&utm_medium=referral&utm_content=decide-update-4-1/decide-update-4.1&utm_campaign=Badge_Coverage) Plataforma voto electrónico educativa ===================================== @@ -222,7 +222,7 @@ para el servidor de base de datos, otro para el django y otro con un servidor web nginx para servir los ficheros estáticos y hacer de proxy al servidor django: - * decide\_db + * decide\_db (PostgreSQL 14 con pgautoupgrade) * decide\_web * decide\_nginx @@ -233,6 +233,11 @@ contenedores se pueden destruir sin miedo a perder datos: * decide\_db * decide\_static +**Nota sobre la actualización de PostgreSQL:** Si vienes de una versión anterior con +PostgreSQL 11, la imagen `pgautoupgrade` se encargará de migrar automáticamente los +datos al formato de PostgreSQL 14 en el primer arranque. Este proceso puede tardar +unos minutos dependiendo del tamaño de la base de datos. + Se puede editar el fichero docker-settings.py para modificar el settings del proyecto django antes de crear las imágenes del contenedor. @@ -472,25 +477,26 @@ Python 3.12. El archivo "populate.json" se ha generado manualmente con ayuda de la documentación encontrada en -[el siguiente portal web](https://docs.djangoproject.com/en/4.1/howto/initial-data/). +[el siguiente portal web](https://docs.djangoproject.com/en/5.2/howto/initial-data/). Versiones actuales ------------------ -En las ultimas actualizaciones se han modificado las versiones usadas por la aplicación Decide. Las +En las ultimas actualizaciones se han modificado las versiones usadas por la aplicación Decide. Las versiones usadas actualmente se corresponden a las siguientes: -* Django = 4.1 +* Django = 5.2 * pycryptodome = 3.15.0 -* djangorestframework = 3.14.0 -* django-cors-headers = 3.13.0 -* requests = 2.28.1 -* django-filter = 22.1 -* psycopg2 = 2.9.4 -* coverage = 6.5.0 -* jsonnet = 0.18.0 +* djangorestframework = 3.15.2 +* django-cors-headers = 4.6.0 +* requests = 2.32.3 +* django-filter = 24.3 +* psycopg2 = 2.9.10 +* coverage = 7.6.10 +* jsonnet = 0.20.0 * drf-spectacular = 0.29.0 * Python = 3.12 -* Vue=3 -* Bootstrap=5.2 -* selenium = 4.7.2 +* Vue = 3 +* Bootstrap = 5.2 +* selenium = 4.27.1 +* PostgreSQL >= 14 From 5d9d2ad5c1a36e5022d7bc1937a34ecd3b4e787a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Ram=C3=ADrez=20de=20la=20Corte?= Date: Wed, 11 Feb 2026 18:31:35 +0100 Subject: [PATCH 6/6] fix: force pip and gunicorn version in Dockerfile --- docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index e471d697a..827b1ca2f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,8 +2,8 @@ from python:3.12-alpine RUN apk add --no-cache postgresql-dev gcc libc-dev gcc g++ make libffi-dev python3-dev build-base -RUN pip install gunicorn -RUN pip install --upgrade pip +RUN pip install --upgrade pip==26.0.1 +RUN pip install gunicorn==25.0.3 WORKDIR /app