Skip to content

Commit e17f46a

Browse files
committed
Update to Django 5.2
- Adapt SQLDeleteCompiler.execute_sql() per django/django@ddefc3f - Remove special-casing of DecimalField calling adapt_decimalfield_value() obsoleted by django/django@1860a1a - Add ExpressionList.as_mql() for django/django@d99985b
1 parent ef82d68 commit e17f46a

File tree

11 files changed

+63
-47
lines changed

11 files changed

+63
-47
lines changed

.evergreen/run-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ python -m pip install -U pip
99
pip install -e .
1010

1111
# Install django and test dependencies
12-
git clone --branch mongodb-5.1.x https://github.com/mongodb-forks/django django_repo
12+
git clone --branch mongodb-5.2.x https://github.com/mongodb-forks/django django_repo
1313
pushd django_repo/tests/
1414
pip install -e ..
1515
pip install -r requirements/py3.txt

.github/workflows/test-python.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
uses: actions/checkout@v4
3434
with:
3535
repository: 'mongodb-forks/django'
36-
ref: 'mongodb-5.1.x'
36+
ref: 'mongodb-5.2.x'
3737
path: 'django_repo'
3838
persist-credentials: false
3939
- name: Install system packages for Django's Python test dependencies

django_mongodb_backend/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "5.1.0b1"
1+
__version__ = "5.2.0a0"
22

33
# Check Django compatibility before other imports which may fail if the
44
# wrong version of Django is installed.

django_mongodb_backend/compiler.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from django.utils.functional import cached_property
1818
from pymongo import ASCENDING, DESCENDING
1919

20-
from .base import Cursor
2120
from .query import MongoQuery, wrap_database_errors
2221

2322

@@ -690,15 +689,12 @@ def collection_name(self):
690689

691690
class SQLDeleteCompiler(compiler.SQLDeleteCompiler, SQLCompiler):
692691
def execute_sql(self, result_type=MULTI):
693-
cursor = Cursor()
694692
try:
695693
query = self.build_query()
696694
except EmptyResultSet:
697-
rowcount = 0
695+
return 0
698696
else:
699-
rowcount = query.delete()
700-
cursor.rowcount = rowcount
701-
return cursor
697+
return query.delete()
702698

703699
def check_query(self):
704700
super().check_query()

django_mongodb_backend/expressions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
Col,
1111
CombinedExpression,
1212
Exists,
13+
ExpressionList,
1314
ExpressionWrapper,
1415
F,
1516
NegatedExpression,
@@ -24,6 +25,8 @@
2425
)
2526
from django.db.models.sql import Query
2627

28+
from .query_utils import process_lhs
29+
2730

2831
def case(self, compiler, connection):
2932
case_parts = []
@@ -83,6 +86,10 @@ def expression_wrapper(self, compiler, connection):
8386
return self.expression.as_mql(compiler, connection)
8487

8588

89+
def expression_list(self, compiler, connection):
90+
return process_lhs(self, compiler, connection)
91+
92+
8693
def f(self, compiler, connection): # noqa: ARG001
8794
return f"${self.name}"
8895

@@ -202,6 +209,7 @@ def register_expressions():
202209
Col.as_mql = col
203210
CombinedExpression.as_mql = combined_expression
204211
Exists.as_mql = exists
212+
ExpressionList.as_mql = expression_list
205213
ExpressionWrapper.as_mql = expression_wrapper
206214
F.as_mql = f
207215
NegatedExpression.as_mql = negated_expression

django_mongodb_backend/features.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,34 @@ class DatabaseFeatures(BaseDatabaseFeatures):
8888
# of $setIsSubset must be arrays. Second argument is of type: null"
8989
# https://jira.mongodb.org/browse/SERVER-99186
9090
"model_fields_.test_arrayfield.QueryingTests.test_contained_by_subquery",
91+
# Broken by https://github.com/django/django/commit/65ad4ade74dc9208b9d686a451cd6045df0c9c3a
92+
"aggregation.tests.AggregateTestCase.test_even_more_aggregate",
93+
"aggregation.tests.AggregateTestCase.test_grouped_annotation_in_group_by",
94+
"aggregation.tests.AggregateTestCase.test_non_grouped_annotation_not_in_group_by",
95+
"aggregation_regress.tests.AggregationTests.test_aggregate_fexpr",
96+
"aggregation_regress.tests.AggregationTests.test_values_list_annotation_args_ordering",
97+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_subquery_and_aggregate_values_chaining",
98+
"annotations.tests.NonAggregateAnnotationTestCase.test_values_fields_annotations_order",
99+
"queries.test_qs_combinators.QuerySetSetOperationTests.test_union_multiple_models_with_values_and_datetime_annotations",
100+
"queries.test_qs_combinators.QuerySetSetOperationTests.test_union_multiple_models_with_values_list_and_datetime_annotations",
101+
"queries.test_qs_combinators.QuerySetSetOperationTests.test_union_multiple_models_with_values_list_and_annotations",
102+
"queries.test_qs_combinators.QuerySetSetOperationTests.test_union_with_field_and_annotation_values",
103+
"queries.test_qs_combinators.QuerySetSetOperationTests.test_union_with_two_annotated_values_list",
104+
"queries.tests.Queries1Tests.test_union_values_subquery",
105+
# JSONArray not implemented.
106+
"db_functions.json.test_json_array.JSONArrayTests",
107+
# Some usage of prefetch_related() raises "ColPairs is not supported."
108+
"known_related_objects.tests.ExistingRelatedInstancesTests.test_one_to_one_multi_prefetch_related",
109+
"known_related_objects.tests.ExistingRelatedInstancesTests.test_one_to_one_prefetch_related",
110+
"prefetch_related.tests.DeprecationTests.test_prefetch_one_level_fallback",
111+
"prefetch_related.tests.MultiDbTests.test_using_is_honored_fkey",
112+
"prefetch_related.tests.MultiDbTests.test_using_is_honored_inheritance",
113+
"prefetch_related.tests.NestedPrefetchTests.test_nested_prefetch_is_not_overwritten_by_related_object",
114+
"prefetch_related.tests.NullableTest.test_prefetch_nullable",
115+
"prefetch_related.tests.Ticket19607Tests.test_bug",
116+
# Value.as_mql() doesn't call output_field.get_db_prep_save():
117+
# https://github.com/mongodb/django-mongodb-backend/issues/282
118+
"model_fields.test_jsonfield.TestSaveLoad.test_bulk_update_custom_get_prep_value",
91119
}
92120
# $bitAnd, #bitOr, and $bitXor are new in MongoDB 6.3.
93121
_django_test_expected_failures_bitwise = {
@@ -112,6 +140,7 @@ def django_test_expected_failures(self):
112140
# bson.errors.InvalidDocument: cannot encode object:
113141
# <django.db.models.expressions.DatabaseDefault
114142
"basic.tests.ModelInstanceCreationTests.test_save_primary_with_db_default",
143+
"basic.tests.ModelInstanceCreationTests.test_save_primary_with_falsey_db_default",
115144
"constraints.tests.UniqueConstraintTests.test_database_default",
116145
"field_defaults.tests.DefaultTests",
117146
"migrations.test_operations.OperationTests.test_add_field_both_defaults",
@@ -194,9 +223,13 @@ def django_test_expected_failures(self):
194223
"prefetch_related.tests.Ticket21410Tests",
195224
"queryset_pickle.tests.PickleabilityTestCase.test_pickle_prefetch_related_with_m2m_and_objects_deletion",
196225
"serializers.test_json.JsonSerializerTestCase.test_serialize_prefetch_related_m2m",
226+
"serializers.test_json.JsonSerializerTestCase.test_serialize_prefetch_related_m2m_with_natural_keys",
197227
"serializers.test_jsonl.JsonlSerializerTestCase.test_serialize_prefetch_related_m2m",
228+
"serializers.test_jsonl.JsonlSerializerTestCase.test_serialize_prefetch_related_m2m_with_natural_keys",
198229
"serializers.test_xml.XmlSerializerTestCase.test_serialize_prefetch_related_m2m",
230+
"serializers.test_xml.XmlSerializerTestCase.test_serialize_prefetch_related_m2m_with_natural_keys",
199231
"serializers.test_yaml.YamlSerializerTestCase.test_serialize_prefetch_related_m2m",
232+
"serializers.test_yaml.YamlSerializerTestCase.test_serialize_prefetch_related_m2m_with_natural_keys",
200233
},
201234
"AutoField not supported.": {
202235
"bulk_create.tests.BulkCreateTests.test_bulk_insert_nullable_fields",
@@ -599,6 +632,13 @@ def django_test_expected_failures(self):
599632
"foreign_object.tests.MultiColumnFKTests",
600633
"foreign_object.tests.TestExtraJoinFilterQ",
601634
},
635+
"Tuple lookups are not supported.": {
636+
"foreign_object.test_tuple_lookups.TupleLookupsTests",
637+
},
638+
"ColPairs is not supported.": {
639+
# 'ColPairs' object has no attribute 'as_mql'
640+
"auth_tests.test_views.CustomUserCompositePrimaryKeyPasswordResetTest",
641+
},
602642
"Custom lookups are not supported.": {
603643
"custom_lookups.tests.BilateralTransformTests",
604644
"custom_lookups.tests.LookupTests.test_basic_lookup",

django_mongodb_backend/fields/array.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from django.contrib.postgres.validators import ArrayMaxLengthValidator
44
from django.core import checks, exceptions
5-
from django.db.models import DecimalField, Field, Func, IntegerField, Transform, Value
5+
from django.db.models import Field, Func, IntegerField, Transform, Value
66
from django.db.models.fields.mixins import CheckFieldDefaultMixin
77
from django.db.models.lookups import Exact, FieldGetDbPrepValueMixin, In, Lookup
88
from django.utils.translation import gettext_lazy as _
@@ -113,10 +113,6 @@ def db_type(self, connection):
113113

114114
def get_db_prep_value(self, value, connection, prepared=False):
115115
if isinstance(value, list | tuple):
116-
# Workaround for https://code.djangoproject.com/ticket/35982
117-
# (fixed in Django 5.2).
118-
if isinstance(self.base_field, DecimalField):
119-
return [self.base_field.get_db_prep_save(i, connection) for i in value]
120116
return [self.base_field.get_db_prep_value(i, connection, prepared=False) for i in value]
121117
return value
122118

django_mongodb_backend/lookups.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.db import NotSupportedError
2-
from django.db.models.fields.related_lookups import In, MultiColSource, RelatedIn
2+
from django.db.models.expressions import ColPairs
3+
from django.db.models.fields.related_lookups import In, RelatedIn
34
from django.db.models.lookups import (
45
BuiltinLookup,
56
FieldGetDbPrepValueIterableMixin,
@@ -34,8 +35,8 @@ def field_resolve_expression_parameter(self, compiler, connection, sql, param):
3435

3536

3637
def in_(self, compiler, connection):
37-
if isinstance(self.lhs, MultiColSource):
38-
raise NotImplementedError("MultiColSource is not supported.")
38+
if isinstance(self.lhs, ColPairs):
39+
raise NotImplementedError("ColPairs is not supported.")
3940
db_rhs = getattr(self.rhs, "_db", None)
4041
if db_rhs is not None and db_rhs != connection.alias:
4142
raise ValueError(

django_mongodb_backend/operations.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -195,28 +195,6 @@ def execute_sql_flush(self, tables):
195195
if not options.get("capped", False):
196196
collection.delete_many({})
197197

198-
def prep_lookup_value(self, value, field, lookup):
199-
"""
200-
Perform type-conversion on `value` before using as a filter parameter.
201-
"""
202-
if getattr(field, "rel", None) is not None:
203-
field = field.rel.get_related_field()
204-
field_kind = field.get_internal_type()
205-
206-
if lookup in ("in", "range"):
207-
return [
208-
self._prep_lookup_value(subvalue, field, field_kind, lookup) for subvalue in value
209-
]
210-
return self._prep_lookup_value(value, field, field_kind, lookup)
211-
212-
def _prep_lookup_value(self, value, field, field_kind, lookup):
213-
if value is None:
214-
return None
215-
216-
if field_kind == "DecimalField":
217-
value = self.adapt_decimalfield_value(value, field.max_digits, field.decimal_places)
218-
return value
219-
220198
def explain_query_prefix(self, format=None, **options):
221199
# Validate options.
222200
validated_options = {}

django_mongodb_backend/query_utils.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@ def process_rhs(node, compiler, connection):
4444
value = value[0]
4545
if hasattr(node, "prep_lookup_value_mongo"):
4646
value = node.prep_lookup_value_mongo(value)
47-
# No need to prepare expressions like F() objects.
48-
if hasattr(rhs, "resolve_expression"):
49-
return value
50-
return connection.ops.prep_lookup_value(value, node.lhs.output_field, node.lookup_name)
47+
return value
5148

5249

5350
def regex_match(field, regex_vals, insensitive=False):

tests/model_forms_/test_embedded_model.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ def test_some_missing_data(self):
182182
required id="id_title">
183183
</div>
184184
<div>
185-
<fieldset>
185+
<fieldset aria-describedby="id_publisher_error">
186186
<legend>Publisher:</legend>
187-
<ul class="errorlist">
187+
<ul class="errorlist" id="id_publisher_error">
188188
<li>Enter all required values.</li>
189189
</ul>
190190
<div>
@@ -252,9 +252,9 @@ def test_invalid_field_data(self):
252252
maxlength="50" required id="id_title">
253253
</div>
254254
<div>
255-
<fieldset>
255+
<fieldset aria-describedby="id_publisher_error">
256256
<legend>Publisher:</legend>
257-
<ul class="errorlist">
257+
<ul class="errorlist" id="id_publisher_error">
258258
<li>Ensure this value has at most 2 characters (it has 8).</li>
259259
</ul>
260260
<div>

0 commit comments

Comments
 (0)