From d798a9e02822f9798ce965a14fab0f787a546320 Mon Sep 17 00:00:00 2001 From: Andy Chosak Date: Tue, 10 Feb 2026 10:38:00 -0500 Subject: [PATCH] Add support for Django 6.0 Django 5.2 LTS ended mainstream support on 12/3/25. This updates the tox testing matrix and GitHub Action to test against Django 6.0 with Python 3.13. It drops explicit testing against 5.1 to keep the matrix from becoming too large. We now test against 4.2, 5.2, and 6.0 (all LTS). We can remove some deprecated Django version checks that were only relevant for older versions. The docs for unique_together indicate that it may be deprecated in future [0]. This note was added to the docs way back in Django 2.2. This commit modernizes our constraint to use models.UniqueConstraint instead. Pyproject classifiers have been updated to add Django 6.0. [0] https://docs.djangoproject.com/en/6.0/ref/models/options/#django.db.models.Options.unique_together --- .github/workflows/test.yml | 8 +++---- docs/releasenotes.md | 8 +++++++ flags/__init__.py | 5 ---- .../0014_flagstate_unique_constraint.py | 24 +++++++++++++++++++ flags/models.py | 7 +++++- flags/tests/test_conditions_validators.py | 8 ------- flags/tests/testapp/__init__.py | 5 ---- pyproject.toml | 1 + tox.ini | 5 ++-- 9 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 flags/migrations/0014_flagstate_unique_constraint.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 63a014a..3987bef 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,14 +35,14 @@ jobs: django: "4.2" - python: "3.13" django: "4.2" - - python: "3.12" - django: "5.1" - - python: "3.13" - django: "5.1" - python: "3.12" django: "5.2" - python: "3.13" django: "5.2" + - python: "3.12" + django: "6.0" + - python: "3.13" + django: "6.0" steps: - uses: actions/checkout@v5 diff --git a/docs/releasenotes.md b/docs/releasenotes.md index c426bf5..42b8379 100644 --- a/docs/releasenotes.md +++ b/docs/releasenotes.md @@ -1,5 +1,13 @@ # Release Notes +## Unreleased + +### What's new? + +- Added support for Django 6.0 +- Removed obsolete Django version checks + + ## 5.1.0 ### What's new? diff --git a/flags/__init__.py b/flags/__init__.py index ac01bc1..e69de29 100644 --- a/flags/__init__.py +++ b/flags/__init__.py @@ -1,5 +0,0 @@ -import django - - -if django.VERSION < (3, 2): - default_app_config = "flags.apps.DjangoFlagsConfig" diff --git a/flags/migrations/0014_flagstate_unique_constraint.py b/flags/migrations/0014_flagstate_unique_constraint.py new file mode 100644 index 0000000..62e4d7b --- /dev/null +++ b/flags/migrations/0014_flagstate_unique_constraint.py @@ -0,0 +1,24 @@ +# Generated by Django 6.0.2 on 2026-02-10 15:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("flags", "0013_add_required_field"), + ] + + operations = [ + migrations.AlterUniqueTogether( + name="flagstate", + unique_together=set(), + ), + migrations.AddConstraint( + model_name="flagstate", + constraint=models.UniqueConstraint( + fields=("name", "condition", "value"), + name="flags_flagstate_unique_name_condition_value", + ), + ), + ] diff --git a/flags/models.py b/flags/models.py index 9d6448b..a29da13 100644 --- a/flags/models.py +++ b/flags/models.py @@ -9,7 +9,12 @@ class FlagState(models.Model): class Meta: app_label = "flags" - unique_together = ("name", "condition", "value") + constraints = [ + models.UniqueConstraint( + fields=["name", "condition", "value"], + name="flags_flagstate_unique_name_condition_value", + ) + ] def __str__(self): return ( diff --git a/flags/tests/test_conditions_validators.py b/flags/tests/test_conditions_validators.py index 3e0db48..ed9c782 100644 --- a/flags/tests/test_conditions_validators.py +++ b/flags/tests/test_conditions_validators.py @@ -1,4 +1,3 @@ -import django from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError from django.test import TestCase, override_settings @@ -89,13 +88,6 @@ def test_invalid_date_strings(self): with self.assertRaises(ValidationError): validate_date("tomorrowish") - # Django 4.0 relies on Python 3.7+'s `datetime.fromisoformat()`, which - # handles this where the old regex did not. This is now valid when on - # Django 4.0+. See https://github.com/django/django/pull/14582 - if django.VERSION < (4, 0): - with self.assertRaises(ValidationError): - validate_date("2020-04-01") - def test_valid_date_strings(self): validate_date("2020-04-01T12:00") validate_date("2020-04-01T12:00+04:00") diff --git a/flags/tests/testapp/__init__.py b/flags/tests/testapp/__init__.py index 2e8a831..e69de29 100644 --- a/flags/tests/testapp/__init__.py +++ b/flags/tests/testapp/__init__.py @@ -1,5 +0,0 @@ -import django - - -if django.VERSION < (3, 2): - default_app_config = "flags.tests.testapp.apps.TestAppConfig" diff --git a/pyproject.toml b/pyproject.toml index 5e9f810..f67dc68 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ classifiers = [ "Framework :: Django :: 4.2", "Framework :: Django :: 5.1", "Framework :: Django :: 5.2", + "Framework :: Django :: 6.0", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", diff --git a/tox.ini b/tox.ini index e4e16e2..6783305 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,8 @@ skipsdist=True envlist= lint, python{3.10,3.13}-django4.2 - python{3.12,3.13}-django{5.1,5.2} + python{3.12,3.13}-django5.2 + python{3.12,3.13}-django6.0 coverage [testenv] @@ -20,8 +21,8 @@ basepython= deps= django4.2: Django~=4.2 - django5.1: Django~=5.1 django5.2: Django~=5.2 + django6.0: Django~=6.0 [testenv:lint] basepython=python3.13