Skip to content

update to Django 5.1 #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .evergreen/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ python -m pip install -U pip
pip install -e .

# Install django and test dependencies
git clone --branch mongodb-5.0.x https://github.com/mongodb-forks/django django_repo
git clone --branch mongodb-5.1.x https://github.com/mongodb-forks/django django_repo
pushd django_repo/tests/
pip install -e ..
pip install -r requirements/py3.txt
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
uses: actions/checkout@v4
with:
repository: 'mongodb-forks/django'
ref: 'mongodb-5.0.x'
ref: 'mongodb-5.1.x'
path: 'django_repo'
persist-credentials: false
- name: Install system packages for Django's Python test dependencies
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ explore and build. The best way to share this is via our [MongoDB Community Foru
## Install

Use the version of `django-mongodb-backend` that corresponds to your version of
Django. For example, to get the latest compatible release for Django 5.0.x:
Django. For example, to get the latest compatible release for Django 5.1.x:
```bash
$ pip install --pre django-mongodb-backend==5.0.*
$ pip install --pre django-mongodb-backend==5.1.*
```
(Until the package is out of beta, you must use pip's `--pre` option.)

Expand All @@ -21,11 +21,11 @@ $ pip install --pre django-mongodb-backend==5.0.*
From your shell, run the following command to create a new Django project
called `example` using our custom template. Make sure the zipfile referenced
at the end of the template link corresponds to your
version of Django. The snippet below specifies `5.0.x.zip` at the end of
the template url to get the template for any Django version matching 5.0:
version of Django. The snippet below specifies `5.1.x.zip` at the end of
the template url to get the template for any Django version matching 5.1:

```bash
$ django-admin startproject example --template https://github.com/mongodb-labs/django-mongodb-project/archive/refs/heads/5.0.x.zip
$ django-admin startproject example --template https://github.com/mongodb-labs/django-mongodb-project/archive/refs/heads/5.1.x.zip
```


Expand Down
2 changes: 1 addition & 1 deletion django_mongodb_backend/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "5.0.0a3"
__version__ = "5.1.0a1"

# Check Django compatibility before other imports which may fail if the
# wrong version of Django is installed.
Expand Down
2 changes: 1 addition & 1 deletion django_mongodb_backend/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def _prepare_expressions_for_pipeline(self, expression, target, annotation_group
rhs = sub_expr.as_mql(self, self.connection, resolve_inner_expression=True)
group[alias] = {"$addToSet": rhs}
replacing_expr = sub_expr.copy()
replacing_expr.set_source_expressions([inner_column])
replacing_expr.set_source_expressions([inner_column, None])
else:
group[alias] = sub_expr.as_mql(self, self.connection)
replacing_expr = inner_column
Expand Down
13 changes: 13 additions & 0 deletions django_mongodb_backend/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ class DatabaseFeatures(BaseDatabaseFeatures):
uses_savepoints = False

_django_test_expected_failures = {
# $concat only supports strings, not int
"db_functions.text.test_concat.ConcatTests.test_concat_non_str",
# QuerySet.order_by() with annotation transform doesn't work:
# "Expression $mod takes exactly 2 arguments. 1 were passed in"
# https://github.com/django/django/commit/b0ad41198b3e333f57351e3fce5a1fb47f23f376
"aggregation.tests.AggregateTestCase.test_order_by_aggregate_transform",
# 'NulledTransform' object has no attribute 'as_mql'.
"lookup.tests.LookupTests.test_exact_none_transform",
# "Save with update_fields did not affect any rows."
Expand Down Expand Up @@ -70,6 +76,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
# Connection creation doesn't follow the usual Django API.
"backends.tests.ThreadTests.test_pass_connection_between_threads",
"backends.tests.ThreadTests.test_default_connection_thread_local",
"test_utils.tests.DisallowedDatabaseQueriesTests.test_disallowed_thread_database_connection",
# Object of type ObjectId is not JSON serializable.
"auth_tests.test_views.LoginTest.test_login_session_without_hash_session_key",
# GenericRelation.value_to_string() assumes integer pk.
Expand Down Expand Up @@ -164,6 +171,7 @@ def django_test_expected_failures(self):
"fixtures.tests.FixtureLoadingTests.test_loading_and_dumping",
"m2m_through_regress.test_multitable.MultiTableTests.test_m2m_prefetch_proxied",
"m2m_through_regress.test_multitable.MultiTableTests.test_m2m_prefetch_reverse_proxied",
"many_to_many.tests.ManyToManyQueryTests.test_prefetch_related_no_queries_optimization_disabled",
"many_to_many.tests.ManyToManyTests.test_add_after_prefetch",
"many_to_many.tests.ManyToManyTests.test_add_then_remove_after_prefetch",
"many_to_many.tests.ManyToManyTests.test_clear_after_prefetch",
Expand Down Expand Up @@ -375,7 +383,11 @@ def django_test_expected_failures(self):
"delete.tests.DeletionTests.test_only_referenced_fields_selected",
"expressions.tests.ExistsTests.test_optimizations",
"lookup.tests.LookupTests.test_in_ignore_none",
"lookup.tests.LookupTests.test_lookup_direct_value_rhs_unwrapped",
"lookup.tests.LookupTests.test_textfield_exact_null",
"many_to_many.tests.ManyToManyQueryTests.test_count_join_optimization_disabled",
"many_to_many.tests.ManyToManyQueryTests.test_exists_join_optimization_disabled",
"many_to_many.tests.ManyToManyTests.test_custom_default_manager_exists_count",
"migrations.test_commands.MigrateTests.test_migrate_syncdb_app_label",
"migrations.test_commands.MigrateTests.test_migrate_syncdb_deferred_sql_executed_with_schemaeditor",
"queries.tests.ExistsSql.test_exists",
Expand Down Expand Up @@ -423,6 +435,7 @@ def django_test_expected_failures(self):
"raw_query.tests.RawQueryTests",
"schema.test_logging.SchemaLoggerTests.test_extra_args",
"schema.tests.SchemaTests.test_remove_constraints_capital_letters",
"test_utils.tests.AllowedDatabaseQueriesTests.test_allowed_database_copy_queries",
"timezones.tests.LegacyDatabaseTests.test_cursor_execute_accepts_naive_datetime",
"timezones.tests.LegacyDatabaseTests.test_cursor_execute_returns_naive_datetime",
"timezones.tests.LegacyDatabaseTests.test_raw_sql",
Expand Down
2 changes: 2 additions & 0 deletions django_mongodb_backend/query_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def process_lhs(node, compiler, connection):
# node is a Func or Expression, possibly with multiple source expressions.
result = []
for expr in node.get_source_expressions():
if expr is None:
continue
try:
result.append(expr.as_mql(compiler, connection))
except FullResultSet:
Expand Down
18 changes: 2 additions & 16 deletions django_mongodb_backend/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ def create_model(self, model):

def _create_model_indexes(self, model, column_prefix="", parent_model=None):
"""
Create all indexes (field indexes & uniques, Meta.index_together,
Meta.unique_together, Meta.constraints, Meta.indexes) for the model.
Create all indexes (field indexes & uniques, Meta.unique_together,
Meta.constraints, Meta.indexes) for the model.

If this is a recursive call due to an embedded model, `column_prefix`
tracks the path that must be prepended to the index's column, and
Expand All @@ -71,11 +71,6 @@ def _create_model_indexes(self, model, column_prefix="", parent_model=None):
self._add_field_index(parent_model or model, field, column_prefix=column_prefix)
elif self._field_should_have_unique(field):
self._add_field_unique(parent_model or model, field, column_prefix=column_prefix)
# Meta.index_together (RemovedInDjango51Warning)
for field_names in model._meta.index_together:
self._add_composed_index(
model, field_names, column_prefix=column_prefix, parent_model=parent_model
)
# Meta.unique_together
if model._meta.unique_together:
self.alter_unique_together(
Expand Down Expand Up @@ -208,15 +203,6 @@ def _remove_model_indexes(self, model, column_prefix="", parent_model=None):
self._remove_field_index(parent_model or model, field, column_prefix=column_prefix)
elif self._field_should_have_unique(field):
self._remove_field_unique(parent_model or model, field, column_prefix=column_prefix)
# Meta.index_together (RemovedInDjango51Warning)
for field_names in model._meta.index_together:
self._remove_composed_index(
model,
field_names,
{"index": True, "unique": False},
column_prefix=column_prefix,
parent_model=parent_model,
)
# Meta.unique_together
if model._meta.unique_together:
self.alter_unique_together(
Expand Down
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@

intersphinx_mapping = {
"django": (
"https://docs.djangoproject.com/en/5.0/",
"http://docs.djangoproject.com/en/5.0/_objects/",
"https://docs.djangoproject.com/en/5.1/",
"http://docs.djangoproject.com/en/5.1/_objects/",
),
"pymongo": ("https://pymongo.readthedocs.io/en/stable/", None),
"python": ("https://docs.python.org/3/", None),
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
django-mongodb-backend 5.0.x documentation
django-mongodb-backend 5.1.x documentation
==========================================

.. toctree::
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ keywords = [
classifiers = [
"Development Status :: 4 - Beta",
"Framework :: Django",
"Framework :: Django :: 5.0",
"Framework :: Django :: 5.1",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
Expand Down
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
# NOTE: this needs to change per branch to track the django version.
django>=5.0,<5.1
django>=5.1,<5.2
pymongo>=4.6,<5.0
115 changes: 1 addition & 114 deletions tests/schema_/test_embedded_model.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import itertools

from django.db import connection, models
from django.test import TransactionTestCase, ignore_warnings
from django.test import TransactionTestCase
from django.test.utils import isolate_apps
from django.utils.deprecation import RemovedInDjango51Warning

from django_mongodb_backend.fields import EmbeddedModelField
from django_mongodb_backend.models import EmbeddedModel
Expand Down Expand Up @@ -131,54 +130,6 @@ def test_unique(self):
editor.delete_model(Book)
self.assertTableNotExists(Author)

@ignore_warnings(category=RemovedInDjango51Warning)
@isolate_apps("schema_")
def test_index_together(self):
"""Meta.index_together on an embedded model."""

class Address(EmbeddedModel):
index_together_one = models.CharField(max_length=10)
index_together_two = models.CharField(max_length=10)

class Meta:
app_label = "schema_"
index_together = [("index_together_one", "index_together_two")]

class Author(models.Model):
address = EmbeddedModelField(Address)
index_together_three = models.CharField(max_length=10)
index_together_four = models.CharField(max_length=10)

class Meta:
app_label = "schema_"
index_together = [("index_together_three", "index_together_four")]

class Book(models.Model):
author = EmbeddedModelField(Author)

class Meta:
app_label = "schema_"

with connection.schema_editor() as editor:
editor.create_model(Book)
self.assertTableExists(Book)
# Embedded uniques are created.
self.assertEqual(
self.get_constraints_for_columns(
Book, ["author.address.index_together_one", "author.address.index_together_two"]
),
["schema__add_index_t_efa93e_idx"],
)
self.assertEqual(
self.get_constraints_for_columns(
Book,
["author.index_together_three", "author.index_together_four"],
),
["schema__aut_index_t_df32aa_idx"],
)
editor.delete_model(Book)
self.assertTableNotExists(Book)

@isolate_apps("schema_")
def test_unique_together(self):
"""Meta.unique_together on an embedded model."""
Expand Down Expand Up @@ -376,70 +327,6 @@ class Meta:
editor.delete_model(Book)
self.assertTableNotExists(Author)

@ignore_warnings(category=RemovedInDjango51Warning)
@isolate_apps("schema_")
def test_add_remove_field_index_together(self):
"""AddField/RemoveField + EmbeddedModelField + Meta.index_together."""

class Address(models.Model):
index_together_one = models.CharField(max_length=10)
index_together_two = models.CharField(max_length=10)

class Meta:
app_label = "schema_"
index_together = [("index_together_one", "index_together_two")]

class Author(models.Model):
address = EmbeddedModelField(Address)
index_together_three = models.CharField(max_length=10)
index_together_four = models.CharField(max_length=10)

class Meta:
app_label = "schema_"
index_together = [("index_together_three", "index_together_four")]

class Book(models.Model):
class Meta:
app_label = "schema_"

new_field = EmbeddedModelField(Author)
new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor:
# Create the table amd add the field.
editor.create_model(Book)
editor.add_field(Book, new_field)
# Embedded index_togethers are created.
self.assertEqual(
self.get_constraints_for_columns(
Book, ["author.address.index_together_one", "author.address.index_together_two"]
),
["schema__add_index_t_efa93e_idx"],
)
self.assertEqual(
self.get_constraints_for_columns(
Book,
["author.index_together_three", "author.index_together_four"],
),
["schema__aut_index_t_df32aa_idx"],
)
editor.remove_field(Book, new_field)
# Embedded indexes are removed.
self.assertEqual(
self.get_constraints_for_columns(
Book, ["author.address.index_together_one", "author.address.index_together_two"]
),
[],
)
self.assertEqual(
self.get_constraints_for_columns(
Book,
["author.index_together_three", "author.index_together_four"],
),
[],
)
editor.delete_model(Book)
self.assertTableNotExists(Book)

@isolate_apps("schema_")
def test_add_remove_field_unique_together(self):
"""AddField/RemoveField + EmbeddedModelField + Meta.unique_together."""
Expand Down
Loading