From 3b0b36e6dafc67eae6ab8bd93f17027d51f88809 Mon Sep 17 00:00:00 2001 From: alec_dev Date: Fri, 1 May 2026 13:19:17 -0500 Subject: [PATCH 1/4] Initial Django 5.2 upgrade --- requirements-testing.txt | 10 ++++++++-- requirements.txt | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/requirements-testing.txt b/requirements-testing.txt index 21bba85648c..30e7f4c4dea 100644 --- a/requirements-testing.txt +++ b/requirements-testing.txt @@ -1,6 +1,12 @@ -django-stubs==1.12.0 +# django-stubs==1.12.0 +django-stubs==5.2.9 mypy==1.5.1 hypothesis>=6.131.9,<7 hypothesis-jsonschema==0.19.0 types-requests==2.28.5 -lxml \ No newline at end of file +lxml +debugpy==1.6.5 +pytest==7.2.1 +pytest-django==4.12.0 +django-extensions==4.1 +# django-debug-toolbar==4.4.6 diff --git a/requirements.txt b/requirements.txt index e424999bd63..c6f3d0a33c8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,14 +5,14 @@ wheel kombu==5.5.2 redis==6.4.0 celery==5.5.1 -Django==4.2.30 +Django==5.2.13 mysqlclient==2.1.1 SQLAlchemy==1.4.54 sqlalchemy2-stubs requests==2.32.4 pycryptodome==3.21.0 PyJWT==2.12.1 -django-auth-ldap==1.2.17 +django-auth-ldap==5.3.0 jsonschema==4.0.1 typing-extensions==4.12.2 stream-zip==0.0.83 From eef1949c1c35548a16db9421a55ce27bc774e17d Mon Sep 17 00:00:00 2001 From: alec_dev Date: Fri, 1 May 2026 13:19:56 -0500 Subject: [PATCH 2/4] Remove old USE_L10N, not needed in new version --- specifyweb/settings/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/specifyweb/settings/__init__.py b/specifyweb/settings/__init__.py index 8430307b407..27bdc60a973 100644 --- a/specifyweb/settings/__init__.py +++ b/specifyweb/settings/__init__.py @@ -150,10 +150,6 @@ def get_sa_db_url(db_name): # to load the internationalization machinery. USE_I18N = True -# If you set this to False, Django will not format dates, numbers and -# calendars according to the current locale -USE_L10N = True - LANGUAGE_COOKIE_NAME='language' # Absolute filesystem path to the directory that will hold user-uploaded files. From ed2cf1d256eeecfc5cd8dfd8834dbb4c73e04f08 Mon Sep 17 00:00:00 2001 From: alec_dev Date: Fri, 1 May 2026 13:21:25 -0500 Subject: [PATCH 3/4] Fix ManyToManyField through_fields for Django upgrade --- .../0045_alter_many_to_many_through_fields.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 specifyweb/specify/migrations/0045_alter_many_to_many_through_fields.py diff --git a/specifyweb/specify/migrations/0045_alter_many_to_many_through_fields.py b/specifyweb/specify/migrations/0045_alter_many_to_many_through_fields.py new file mode 100644 index 00000000000..171a4652649 --- /dev/null +++ b/specifyweb/specify/migrations/0045_alter_many_to_many_through_fields.py @@ -0,0 +1,46 @@ +# Generated by Django 5.2.13 on 2026-04-30 + +from django.db import migrations, models + +class Migration(migrations.Migration): + dependencies = [ + ('specify', '0044_alter_deletion_cascade'), + ] + + operations = [ + migrations.AlterField( + model_name='autonumberingscheme', + name='collections', + field=models.ManyToManyField(related_name='numberingschemes', through='specify.Autonumschcoll', through_fields=('autonumberingscheme', 'collection'), to='specify.collection'), + ), + migrations.AlterField( + model_name='autonumberingscheme', + name='disciplines', + field=models.ManyToManyField(related_name='numberingschemes', through='specify.Autonumschdsp', through_fields=('autonumberingscheme', 'discipline'), to='specify.discipline'), + ), + migrations.AlterField( + model_name='autonumberingscheme', + name='divisions', + field=models.ManyToManyField(related_name='numberingschemes', through='specify.Autonumschdiv', through_fields=('autonumberingscheme', 'division'), to='specify.division'), + ), + migrations.AlterField( + model_name='project', + name='collectionobjects', + field=models.ManyToManyField(related_name='projects', through='specify.Project_colobj', through_fields=('project', 'collectionobject'), to='specify.collectionobject'), + ), + migrations.AlterField( + model_name='specifyuser', + name='spprincipals', + field=models.ManyToManyField(related_name='specifyusers', through='specify.Specifyuser_spprincipal', through_fields=('specifyuser', 'spprincipal'), to='specify.spprincipal'), + ), + migrations.AlterField( + model_name='spexportschema', + name='mappings', + field=models.ManyToManyField(related_name='spexportschemas', through='specify.Spexportschema_exportmapping', through_fields=('spexportschema', 'spexportschemamapping'), to='specify.spexportschemamapping'), + ), + migrations.AlterField( + model_name='spprincipal', + name='sppermissions', + field=models.ManyToManyField(related_name='spprincipals', through='specify.Spprincipal_sppermission', through_fields=('spprincipal', 'sppermission'), to='specify.sppermission'), + ), + ] From 0033c8dfcde9eece917b137123c8d971c894d506 Mon Sep 17 00:00:00 2001 From: alec_dev Date: Fri, 1 May 2026 13:22:29 -0500 Subject: [PATCH 4/4] Replace the removed models.NullBooleanField inheritance with a local nullable BooleanField --- specifyweb/specify/utils/case_insensitive_bool.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/specifyweb/specify/utils/case_insensitive_bool.py b/specifyweb/specify/utils/case_insensitive_bool.py index 80f48445ef5..bdb79f17e82 100644 --- a/specifyweb/specify/utils/case_insensitive_bool.py +++ b/specifyweb/specify/utils/case_insensitive_bool.py @@ -9,7 +9,12 @@ def to_python(self, value): return False return super().to_python(value) -class NullBooleanField(models.NullBooleanField): +class NullBooleanField(BooleanField): + def __init__(self, *args, **kwargs): + kwargs.setdefault('null', True) + kwargs.setdefault('blank', True) + super().__init__(*args, **kwargs) + def to_python(self, value): if value == 'true': return True