From 2bee4e8904b7b2c92830aa3af2e10b9a753a375f Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 15 Mar 2026 01:04:25 +0530 Subject: [PATCH 1/6] =?UTF-8?q?Upgrade=20Wagtail=206.0.6=20=E2=86=92=206.3?= =?UTF-8?q?.1=20LTS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename PASSWORD_REQUIRED_TEMPLATE to WAGTAIL_PASSWORD_REQUIRED_TEMPLATE (deprecated in Wagtail 6.1, removed in 7.0) - Bump wagtail from 6.0.6 to 6.3.1 (previous LTS) - All checks pass, 7 new migrations applied cleanly --- publichealth/settings/base.py | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/publichealth/settings/base.py b/publichealth/settings/base.py index dcd7c99..ec638a5 100644 --- a/publichealth/settings/base.py +++ b/publichealth/settings/base.py @@ -152,7 +152,7 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] -PASSWORD_REQUIRED_TEMPLATE = 'password.html' +WAGTAIL_PASSWORD_REQUIRED_TEMPLATE = 'password.html' # Internationalization # https://docs.djangoproject.com/en/1.8/topics/i18n/ diff --git a/requirements.txt b/requirements.txt index 02ebeb5..dcef51e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ # Core Django==5.0.9 # Django 5.0 (latest stable in 5.0 series) -wagtail==6.0.6 # Wagtail 6.0 supports Django 5.0 +wagtail==6.3.1 # Wagtail 6.3 LTS (step 1 of upgrade to 7.0) elasticsearch==7.17.9 # Compatible with Django 5.0 # Database From 5f1653bb6b6111f2b68bd941eae0dc936ed30700 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 15 Mar 2026 01:06:53 +0530 Subject: [PATCH 2/6] =?UTF-8?q?Upgrade=20Wagtail=206.3.1=20=E2=86=92=207.0?= =?UTF-8?q?.2=20LTS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bump wagtail to 7.0.2 (target LTS) - Bump wagtail-modeladmin to 2.2.0 (Wagtail 7.0 support) - Bump django-filter to >=24.0,<25 - Switch elasticsearch backend from elasticsearch5 to elasticsearch7 (elasticsearch5 backend removed in Wagtail 7.0) - All checks pass, 1 migration applied cleanly --- publichealth/settings/production.py | 2 +- requirements.txt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/publichealth/settings/production.py b/publichealth/settings/production.py index c8f0294..c2f56e9 100644 --- a/publichealth/settings/production.py +++ b/publichealth/settings/production.py @@ -131,7 +131,7 @@ if REDIS_LOCATION is not None: if 'ELASTICSEARCH_URL' in env: WAGTAILSEARCH_BACKENDS = { 'default': { - 'BACKEND': 'wagtail.search.backends.elasticsearch5', + 'BACKEND': 'wagtail.search.backends.elasticsearch7', 'URLS': [env['ELASTICSEARCH_URL']], 'INDEX': APP_NAME, 'ATOMIC_REBUILD': True, diff --git a/requirements.txt b/requirements.txt index dcef51e..cc32f30 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ # Core Django==5.0.9 # Django 5.0 (latest stable in 5.0 series) -wagtail==6.3.1 # Wagtail 6.3 LTS (step 1 of upgrade to 7.0) +wagtail==7.0.2 # Wagtail 7.0 LTS (target) elasticsearch==7.17.9 # Compatible with Django 5.0 # Database @@ -39,11 +39,11 @@ unidecode # Additional dependencies for Django 5.0 and Wagtail 6 django-configurations django-taggit>=5.0.0 # Required by Wagtail 6 -wagtail-modeladmin==2.0.0 # Separate package for ModelAdmin in Wagtail 5+ +wagtail-modeladmin==2.2.0 # Separate package for ModelAdmin in Wagtail 5+ (supports 7.0) djangorestframework>=3.15.0 # Required by Wagtail API django-modelcluster>=6.3 # Required by Wagtail 6 django-treebeard>=4.7 # Required by Wagtail 6 -django-filter>=23.3,<24 # Required by Wagtail 6.0.6 (must be <24) +django-filter>=24.0,<25 # Required by Wagtail 7.0 (pinned <25 until Django 5.2) Willow>=1.8.0 # Required by Wagtail for images beautifulsoup4>=4.12.0 # Required by Wagtail html5lib>=1.1 # Required by Wagtail From 95edd2ab88359153391185b5fe7ba050324999be Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 15 Mar 2026 01:08:33 +0530 Subject: [PATCH 3/6] =?UTF-8?q?Upgrade=20Django=205.0.9=20=E2=86=92=205.1.?= =?UTF-8?q?9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bump Django from 5.0.9 to 5.1.9 (intermediate step toward 5.2 LTS) - Generate migrations for BigAutoField id fields and updated field definitions - No code changes needed (STORAGES already used, no index_together) - All checks pass, migrations applied cleanly --- ...try_id_alter_feedlysettings_id_and_more.py | 28 ++++++++ ...elatedlink_id_alter_contact_id_and_more.py | 64 +++++++++++++++++++ requirements.txt | 2 +- 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 feedler/migrations/0010_alter_entry_id_alter_feedlysettings_id_and_more.py create mode 100644 publichealth/home/migrations/0038_alter_articlerelatedlink_id_alter_contact_id_and_more.py diff --git a/feedler/migrations/0010_alter_entry_id_alter_feedlysettings_id_and_more.py b/feedler/migrations/0010_alter_entry_id_alter_feedlysettings_id_and_more.py new file mode 100644 index 0000000..2cbb7db --- /dev/null +++ b/feedler/migrations/0010_alter_entry_id_alter_feedlysettings_id_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 5.1.9 on 2026-03-14 19:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('feedler', '0009_entry_expire_at'), + ] + + operations = [ + migrations.AlterField( + model_name='entry', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='feedlysettings', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='stream', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + ] diff --git a/publichealth/home/migrations/0038_alter_articlerelatedlink_id_alter_contact_id_and_more.py b/publichealth/home/migrations/0038_alter_articlerelatedlink_id_alter_contact_id_and_more.py new file mode 100644 index 0000000..f531633 --- /dev/null +++ b/publichealth/home/migrations/0038_alter_articlerelatedlink_id_alter_contact_id_and_more.py @@ -0,0 +1,64 @@ +# Generated by Django 5.1.9 on 2026-03-14 19:37 + +import wagtail.contrib.forms.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0037_auto_20230516_1241'), + ] + + operations = [ + migrations.AlterField( + model_name='articlerelatedlink', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='contact', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='contactform', + name='from_address', + field=models.EmailField(blank=True, max_length=255, verbose_name='from address'), + ), + migrations.AlterField( + model_name='contactform', + name='to_address', + field=models.CharField(blank=True, help_text='Optional - form submissions will be emailed to these addresses. Separate multiple addresses by comma.', max_length=255, validators=[wagtail.contrib.forms.models.validate_to_address], verbose_name='to address'), + ), + migrations.AlterField( + model_name='contactformfield', + name='choices', + field=models.TextField(blank=True, help_text='Comma or new line separated list of choices. Only applicable in checkboxes, radio and dropdown.', verbose_name='choices'), + ), + migrations.AlterField( + model_name='contactformfield', + name='default_value', + field=models.TextField(blank=True, help_text='Default value. Comma or new line separated values supported for checkboxes.', verbose_name='default value'), + ), + migrations.AlterField( + model_name='contactformfield', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='dataletssettings', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='socialcontact', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='socialcontact', + name='network', + field=models.CharField(choices=[('twitter', 'Twitter'), ('facebook', 'Facebook'), ('linkedin', 'LinkedIn')], default='twitter', max_length=16), + ), + ] diff --git a/requirements.txt b/requirements.txt index cc32f30..cce3243 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ # Updated: 2025-09-18 - Django 5.0 Upgrade # Core -Django==5.0.9 # Django 5.0 (latest stable in 5.0 series) +Django==5.1.9 # Django 5.1 (intermediate step toward 5.2 LTS) wagtail==7.0.2 # Wagtail 7.0 LTS (target) elasticsearch==7.17.9 # Compatible with Django 5.0 From b5229e1eaf5145c3f74c449db3d72b3a313d099e Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 15 Mar 2026 01:12:15 +0530 Subject: [PATCH 4/6] =?UTF-8?q?Upgrade=20Django=205.1.9=20=E2=86=92=205.2.?= =?UTF-8?q?1=20LTS=20+=20bump=20all=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bump Django from 5.1.9 to 5.2.1 (target LTS, supported until April 2028) - Bump django-anymail 11.0 → 12.0, django-colorful 1.3 → 1.4.0, django-crispy-forms 2.3 → 2.5, django-el-pagination 3.3.0 → 4.1.2, django-taggit >=5.0 → >=6.0, Pillow 10.4.0 → 11.1.0 - Remove django-filter <25 pin (no longer needed with Django 5.2) - Add missing django-libsass==0.9 to requirements (SCSS compilation) - No new migrations needed, all checks pass - HTTP smoke tests: homepage, admin, search all return 200 --- requirements.txt | 51 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/requirements.txt b/requirements.txt index cce3243..235f546 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,33 +1,34 @@ -# Updated: 2025-09-18 - Django 5.0 Upgrade +# Updated: 2026-03-15 - Django 5.2 LTS + Wagtail 7.0 LTS Upgrade # Core -Django==5.1.9 # Django 5.1 (intermediate step toward 5.2 LTS) +Django==5.2.1 # Django 5.2 LTS (target) wagtail==7.0.2 # Wagtail 7.0 LTS (target) -elasticsearch==7.17.9 # Compatible with Django 5.0 +elasticsearch==7.17.9 # Compatible with Django 5.2 # Database -psycopg2-binary==2.9.10 # Compatible with Django 5.0 and Python 3.13 -dj-database-url==2.2.0 # Updated for Django 5.0 +psycopg2-binary==2.9.10 # Compatible with Django 5.2 and Python 3.13 +dj-database-url==2.2.0 # Updated for Django 5.2 # Content -# Note: puput needs update or replacement for Wagtail 6.x +# Note: puput needs update or replacement for Wagtail 7.x # puput==2.0.0 guess-language-spirit==0.5.3 # Caching -django-redis==5.4.0 # Compatible with Django 5.0 +django-redis==5.4.0 # Compatible with Django 5.2 redis==5.0.8 # Frontend -django-anymail==11.0 # Updated for Django 5.0 -django-colorful==1.3 -django-contrib-comments==2.2.0 # May need testing with Django 5.0 -django-crispy-forms==2.3 # Updated for Django 5.0 -django-el-pagination==3.3.0 -django-compressor==4.5.1 # Updated for Django 5.0 -django-social-share==2.3.0 # May need testing with Django 5.0 -libsass==0.23.0 # Updated version -Pillow==10.4.0 # Updated for Django 5.0 and Python 3.12+ +django-anymail==12.0 # Updated for Django 5.2 +django-colorful==1.4.0 # Updated for Django 5.2 +django-contrib-comments==2.2.0 # Kept as-is (unused in templates) +django-crispy-forms==2.5 # Updated for Django 5.2 +django-el-pagination==4.1.2 # Updated (latest available) +django-compressor==4.5.1 # Compatible with Django 5.2 +django-social-share==2.3.0 # Compatible with Django 5.2 +libsass==0.23.0 +django-libsass==0.9 # Required by COMPRESS_PRECOMPILERS setting +Pillow==11.1.0 # Updated for Django 5.2 and Python 3.13 # Runtime dependencies gunicorn @@ -36,19 +37,19 @@ python-dotenv #ConcurrentLogHandler unidecode -# Additional dependencies for Django 5.0 and Wagtail 6 +# Additional dependencies for Django 5.2 and Wagtail 7.0 django-configurations -django-taggit>=5.0.0 # Required by Wagtail 6 -wagtail-modeladmin==2.2.0 # Separate package for ModelAdmin in Wagtail 5+ (supports 7.0) +django-taggit>=6.0.0 # Required by Wagtail 7.0 +wagtail-modeladmin==2.2.0 # Separate package for ModelAdmin (supports Wagtail 7.0) djangorestframework>=3.15.0 # Required by Wagtail API -django-modelcluster>=6.3 # Required by Wagtail 6 -django-treebeard>=4.7 # Required by Wagtail 6 -django-filter>=24.0,<25 # Required by Wagtail 7.0 (pinned <25 until Django 5.2) +django-modelcluster>=6.3 # Required by Wagtail 7.0 +django-treebeard>=4.7 # Required by Wagtail 7.0 +django-filter>=24.0 # Required by Wagtail 7.0 Willow>=1.8.0 # Required by Wagtail for images beautifulsoup4>=4.12.0 # Required by Wagtail html5lib>=1.1 # Required by Wagtail openpyxl>=3.1.0 # For Excel export support l18n # For Wagtail localization -telepath>=0.3.1 # Required by Wagtail 6 -# Django 5.0 timezone support (replaces pytz) -tzdata # For timezone support in Django 5.0 +telepath>=0.3.1 # Required by Wagtail 7.0 +# Django 5.x timezone support (replaces pytz) +tzdata # For timezone support in Django 5.x From 8575d2673992ece9598e582c36214ccd8a31a094 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 15 Mar 2026 01:23:49 +0530 Subject: [PATCH 5/6] Fix startup warnings: naive datetime and WAGTAILADMIN_BASE_URL - Replace datetime.datetime.now() with timezone.now() in feedler/models/models.py and publichealth/home/models/models.py (fixes RuntimeWarning about naive datetime with USE_TZ=True) - Add WAGTAILADMIN_BASE_URL to dev.py and production.py (fixes wagtailadmin.W003 warning) - All checks pass with -Wall, no warnings remain except third-party guess_language PyEnchant ImportWarning --- feedler/models/models.py | 6 ++---- publichealth/home/models/models.py | 6 ++---- publichealth/settings/dev.py | 1 + publichealth/settings/production.py | 1 + 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/feedler/models/models.py b/feedler/models/models.py index 70949d8..374a662 100644 --- a/feedler/models/models.py +++ b/feedler/models/models.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- -import datetime - from django.db import models -from django.utils import translation +from django.utils import timezone, translation from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.utils.translation import gettext_lazy as _ from wagtail.models import Page, Orderable # wagtail.core moved to wagtail in v3+ @@ -75,7 +73,7 @@ class FeedPage(Page): def feedentries(self): if self.stream: entries = Entry.objects.filter(stream=self.stream).filter( - models.Q(expire_at__isnull=True) | models.Q(expire_at__gt=datetime.datetime.now()) + models.Q(expire_at__isnull=True) | models.Q(expire_at__gt=timezone.now()) ) else: entries = Entry.objects.all() diff --git a/publichealth/home/models/models.py b/publichealth/home/models/models.py index cdd4674..b3cdde4 100644 --- a/publichealth/home/models/models.py +++ b/publichealth/home/models/models.py @@ -2,10 +2,8 @@ from __future__ import unicode_literals -import datetime - from django.db import models -from django.utils import translation +from django.utils import timezone, translation from django.conf import settings from modelcluster.fields import ParentalKey @@ -367,7 +365,7 @@ class HomePage(Page): def newsentries(self): # Get the last few news entries for the home page entries = Entry.objects.filter( - models.Q(expire_at__isnull=True) | models.Q(expire_at__gt=datetime.datetime.now()) + models.Q(expire_at__isnull=True) | models.Q(expire_at__gt=timezone.now()) ).all().order_by('-published') # Filter out by current language curlang = translation.get_language() diff --git a/publichealth/settings/dev.py b/publichealth/settings/dev.py index afa6a7d..685d37c 100644 --- a/publichealth/settings/dev.py +++ b/publichealth/settings/dev.py @@ -14,6 +14,7 @@ ALLOWED_HOSTS = ['*'] INTERNAL_IPS = ('127.0.0.1', '10.0.2.2') BASE_URL = 'http://localhost:8000' +WAGTAILADMIN_BASE_URL = 'http://localhost:8000' EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' diff --git a/publichealth/settings/production.py b/publichealth/settings/production.py index c2f56e9..e94584b 100644 --- a/publichealth/settings/production.py +++ b/publichealth/settings/production.py @@ -48,6 +48,7 @@ if 'ALLOWED_HOSTS' in env: if 'PRIMARY_HOST' in env: BASE_URL = 'http://%s/' % env['PRIMARY_HOST'] + WAGTAILADMIN_BASE_URL = 'https://%s' % env['PRIMARY_HOST'] # Also add PRIMARY_HOST to CSRF_TRUSTED_ORIGINS CSRF_TRUSTED_ORIGINS = ['https://%s' % env['PRIMARY_HOST'], 'http://%s' % env['PRIMARY_HOST']] From e112569f11ac0b1b888c6906ed0e44d53f6f51a7 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 15 Mar 2026 01:30:35 +0530 Subject: [PATCH 6/6] Remove upgrade-publichealth.md from tracking and add upgrade* to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c68e03d..a68303c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ env /publichealth/static/libs publichealth.home.json .history +upgrade*