From b35700036e7d7a26f9ff07ad1f7a4282f7bd497a Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 23 Sep 2025 14:05:48 -0400 Subject: [PATCH 1/2] Update to Django 6.1 --- .evergreen/run-tests.sh | 2 +- .github/workflows/test-python-atlas.yml | 2 +- .github/workflows/test-python-geo.yml | 2 +- .github/workflows/test-python.yml | 2 +- django_mongodb_backend/__init__.py | 2 +- django_mongodb_backend/features.py | 5 +++++ 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.evergreen/run-tests.sh b/.evergreen/run-tests.sh index 46f02be16..95fc45c5a 100644 --- a/.evergreen/run-tests.sh +++ b/.evergreen/run-tests.sh @@ -9,7 +9,7 @@ python -m pip install -U pip pip install -e . # Install django and test dependencies -git clone --branch mongodb-6.0.x https://github.com/mongodb-forks/django django_repo +git clone --branch mongodb-6.1.x https://github.com/mongodb-forks/django django_repo pushd django_repo/tests/ pip install -e .. pip install -r requirements/py3.txt diff --git a/.github/workflows/test-python-atlas.yml b/.github/workflows/test-python-atlas.yml index bbda0f9f4..1729b729e 100644 --- a/.github/workflows/test-python-atlas.yml +++ b/.github/workflows/test-python-atlas.yml @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@v6 with: repository: 'mongodb-forks/django' - ref: 'mongodb-6.0.x' + ref: 'mongodb-6.1.x' path: 'django_repo' persist-credentials: false - name: Install system packages for Django's Python test dependencies diff --git a/.github/workflows/test-python-geo.yml b/.github/workflows/test-python-geo.yml index aeddd206f..7446a164d 100644 --- a/.github/workflows/test-python-geo.yml +++ b/.github/workflows/test-python-geo.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@v6 with: repository: 'mongodb-forks/django' - ref: 'mongodb-6.0.x' + ref: 'mongodb-6.1.x' path: 'django_repo' persist-credentials: false - name: Install system packages for Django's Python test dependencies diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 584117622..12e797eb1 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@v6 with: repository: 'mongodb-forks/django' - ref: 'mongodb-6.0.x' + ref: 'mongodb-6.1.x' path: 'django_repo' persist-credentials: false - name: Install system packages for Django's Python test dependencies diff --git a/django_mongodb_backend/__init__.py b/django_mongodb_backend/__init__.py index e4850c90a..3fb530b67 100644 --- a/django_mongodb_backend/__init__.py +++ b/django_mongodb_backend/__init__.py @@ -1,4 +1,4 @@ -__version__ = "6.0.1.dev0" +__version__ = "6.1.0.dev0" # Check Django compatibility before other imports which may fail if the # wrong version of Django is installed. diff --git a/django_mongodb_backend/features.py b/django_mongodb_backend/features.py index e5f0b2cf2..f9be655ee 100644 --- a/django_mongodb_backend/features.py +++ b/django_mongodb_backend/features.py @@ -35,6 +35,9 @@ class DatabaseFeatures(GISFeatures, BaseDatabaseFeatures): supports_json_field_contains = False # BSON Date type doesn't support microsecond precision. supports_microsecond_precision = False + supports_on_delete_db_cascade = False + supports_on_delete_db_default = False + supports_on_delete_db_null = False supports_paramstyle_pyformat = False supports_select_difference = False supports_select_intersection = False @@ -465,6 +468,8 @@ def django_test_expected_failures(self): # There is no way to distinguish between a JSON "null" (represented # by Value(None, JSONField())) and a SQL null (queried using the # isnull lookup). Both of these queries return both nulls. + "model_fields.test_jsonfield.JSONExactNoneDeprecationTests", + "model_fields.test_jsonfield.JSONNullTests", "model_fields.test_jsonfield.TestSaveLoad.test_json_null_different_from_sql_null", # Some queries with Q objects, e.g. Q(value__foo="bar"), don't work # properly, particularly with QuerySet.exclude(). From a7e2f60bde65632191a1f33af3227f59e08df5fc Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 23 Sep 2025 14:06:11 -0400 Subject: [PATCH 2/2] Use DatabaseOperations.adapt_durationfield_value() (new in Django 6.1) --- django_mongodb_backend/fields/__init__.py | 2 -- django_mongodb_backend/fields/duration.py | 18 ------------------ django_mongodb_backend/operations.py | 9 +++++++++ 3 files changed, 9 insertions(+), 20 deletions(-) delete mode 100644 django_mongodb_backend/fields/duration.py diff --git a/django_mongodb_backend/fields/__init__.py b/django_mongodb_backend/fields/__init__.py index 0c95afd69..aecde51de 100644 --- a/django_mongodb_backend/fields/__init__.py +++ b/django_mongodb_backend/fields/__init__.py @@ -1,6 +1,5 @@ from .array import ArrayField from .auto import ObjectIdAutoField -from .duration import register_duration_field from .embedded_model import EmbeddedModelField from .embedded_model_array import EmbeddedModelArrayField from .json import register_json_field @@ -21,5 +20,4 @@ def register_fields(): - register_duration_field() register_json_field() diff --git a/django_mongodb_backend/fields/duration.py b/django_mongodb_backend/fields/duration.py deleted file mode 100644 index f6ec18736..000000000 --- a/django_mongodb_backend/fields/duration.py +++ /dev/null @@ -1,18 +0,0 @@ -from bson import Int64 -from django.db.models.fields import DurationField - -_get_db_prep_value = DurationField.get_db_prep_value - - -def get_db_prep_value(self, value, connection, prepared=False): - """DurationField stores milliseconds rather than microseconds.""" - value = _get_db_prep_value(self, value, connection, prepared) - if connection.vendor == "mongodb" and value is not None: - value //= 1000 - # Store value as Int64 (long). - value = Int64(value) - return value - - -def register_duration_field(): - DurationField.get_db_prep_value = get_db_prep_value diff --git a/django_mongodb_backend/operations.py b/django_mongodb_backend/operations.py index 5106678cc..e446e2c44 100644 --- a/django_mongodb_backend/operations.py +++ b/django_mongodb_backend/operations.py @@ -66,6 +66,15 @@ def adapt_decimalfield_value(self, value, max_digits=None, decimal_places=None): return None return Decimal128(value) + def adapt_durationfield_value(self, value): + """DurationField stores milliseconds rather than microseconds.""" + value = super().adapt_durationfield_value(value) + if value is not None: + value //= 1000 + # Store value as Int64 (long). + value = Int64(value) + return value + def adapt_integerfield_value(self, value, internal_type): """Store non-SmallIntegerField variants as Int64 (long).""" if value is None: