Skip to content

Commit 1ee3e1d

Browse files
committed
INTPYTHON-924 Deprecate inline constraints/indexes on embedded models
1 parent a766be5 commit 1ee3e1d

4 files changed

Lines changed: 220 additions & 1 deletion

File tree

django_mongodb_backend/models.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.core import checks
12
from django.db import NotSupportedError, models
23

34
from .managers import EmbeddedModelManager
@@ -9,6 +10,65 @@ class EmbeddedModel(models.Model):
910
class Meta:
1011
abstract = True
1112

13+
@classmethod
14+
def check(self, **kwargs):
15+
errors = super().check(**kwargs)
16+
for field in self._meta.fields:
17+
# Ignore auto-created primary keys.
18+
if field.auto_created:
19+
continue
20+
if field.db_index:
21+
errors.append(
22+
checks.Warning(
23+
"Using db_index=True on embedded fields is deprecated "
24+
"in favor of using EmbeddedFieldIndex in Meta.indexes "
25+
"on the top-level model.",
26+
obj=field,
27+
id="mongodb.fields.embedded_model.W004",
28+
)
29+
)
30+
if field.unique:
31+
errors.append(
32+
checks.Warning(
33+
"Using unique=True on embedded fields is deprecated "
34+
"in favor of using EmbeddedFieldUniqueConstraint in "
35+
"Meta.constraints on the top-level model.",
36+
obj=field,
37+
id="mongodb.fields.embedded_model.W005",
38+
)
39+
)
40+
if self._meta.constraints:
41+
errors.append(
42+
checks.Warning(
43+
"Using Meta.constraints on embedded models is deprecated "
44+
"in favor of using EmbeddedFieldUniqueConstraint in "
45+
"Meta.constraints on the top-level model.",
46+
obj=self,
47+
id="mongodb.fields.embedded_model.W006",
48+
)
49+
)
50+
if self._meta.indexes:
51+
errors.append(
52+
checks.Warning(
53+
"Using Meta.indexes on embedded models is deprecated in "
54+
"favor of using EmbeddedFieldIndex in Meta.indexes on the "
55+
"top-level model.",
56+
obj=self,
57+
id="mongodb.fields.embedded_model.W007",
58+
)
59+
)
60+
if self._meta.unique_together:
61+
errors.append(
62+
checks.Warning(
63+
"Using Meta.unique_together on embedded models is "
64+
"deprecated in favor of using EmbeddedFieldUniqueConstraint "
65+
"in Meta.constraints on the top-level model.",
66+
obj=self,
67+
id="mongodb.fields.embedded_model.W008",
68+
)
69+
)
70+
return errors
71+
1272
def delete(self, *args, **kwargs):
1373
raise NotSupportedError("EmbeddedModels cannot be deleted.")
1474

docs/internals/deprecation.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,47 @@ Deprecation Timeline
55
This document outlines when various pieces of Django MongoDB Backend will be
66
removed or altered in a backward incompatible way, following their deprecation.
77

8+
6.1
9+
---
10+
11+
.. _inline-constraints-and-indexes-deprecation:
12+
13+
Inline constraints and indexes on embedded models
14+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15+
16+
Defining indexes and constraints on embedded models using ``unique=True``,
17+
``db_index=True``, ``Meta.constraints``, ``Meta.indexes``, and
18+
``Meta.unique_together`` will no longer be supported. Instead, use
19+
:class:`~django_mongodb_backend.indexes.EmbeddedFieldIndex` and
20+
:class:`~django_mongodb_backend.constraints.EmbeddedFieldUniqueConstraint` on
21+
the top-level model.
22+
23+
For example, instead of::
24+
25+
class Target(EmbeddedModel):
26+
foo = models.IntegerField(unique=True)
27+
28+
29+
class MyModel(models.Model):
30+
field = EmbeddedModelField(Target)
31+
32+
use::
33+
34+
from django_mongodb_backend.indexes import EmbeddedFieldUniqueConstraint
35+
36+
37+
class Target(EmbeddedModel):
38+
foo = models.IntegerField()
39+
40+
41+
class MyModel(models.Model):
42+
field = EmbeddedModelField(Target)
43+
44+
class Meta:
45+
constraints = [
46+
EmbeddedFieldUniqueConstraint(fields=["field.foo"], name="..."),
47+
]
48+
849
6.0
950
---
1051

docs/releases/6.0.x.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ Bug fixes
3535
that references in migrations don't need to be adjusted if models are later
3636
removed.
3737

38+
Deprecated features
39+
-------------------
40+
41+
- Defining indexes and constraints on embedded models using ``unique=True``,
42+
``db_index=True``, ``Meta.constraints``, ``Meta.indexes``, and
43+
``Meta.unique_together`` is deprecated in favor of using
44+
:class:`~django_mongodb_backend.indexes.EmbeddedFieldIndex` and
45+
:class:`~django_mongodb_backend.constraints.EmbeddedFieldUniqueConstraint`
46+
on the top-level model. See :ref:`inline-constraints-and-indexes-deprecation`
47+
for an example.
48+
3849
6.0.2
3950
=====
4051

tests/models_/test_embedded_model.py

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
from django.db import NotSupportedError
1+
from django.core import checks
2+
from django.db import NotSupportedError, models
23
from django.test import SimpleTestCase
4+
from django.test.utils import isolate_apps
5+
6+
from django_mongodb_backend.models import EmbeddedModel
37

48
from .models import Embed
59

@@ -16,6 +20,109 @@ def test_delete(self):
1620
e.delete()
1721

1822

23+
@isolate_apps("models_")
24+
class TestChecks(SimpleTestCase):
25+
def test_db_index(self):
26+
class Target(EmbeddedModel):
27+
foo = models.IntegerField(db_index=True)
28+
29+
errors = Target().check()
30+
self.assertEqual(
31+
errors,
32+
[
33+
checks.Warning(
34+
"Using db_index=True on embedded fields is deprecated "
35+
"in favor of using EmbeddedFieldIndex in Meta.indexes "
36+
"on the top-level model.",
37+
id="mongodb.fields.embedded_model.W004",
38+
obj=Target._meta.get_field("foo"),
39+
)
40+
],
41+
)
42+
43+
def test_unique(self):
44+
class Target(EmbeddedModel):
45+
foo = models.IntegerField(unique=True)
46+
47+
errors = Target().check()
48+
self.assertEqual(
49+
errors,
50+
[
51+
checks.Warning(
52+
"Using unique=True on embedded fields is deprecated "
53+
"in favor of using EmbeddedFieldUniqueConstraint in "
54+
"Meta.constraints on the top-level model.",
55+
id="mongodb.fields.embedded_model.W005",
56+
obj=Target._meta.get_field("foo"),
57+
)
58+
],
59+
)
60+
61+
def test_constraints(self):
62+
class Target(EmbeddedModel):
63+
foo = models.IntegerField()
64+
65+
class Meta:
66+
constraints = [models.UniqueConstraint(fields=["foo"], name="name")]
67+
68+
errors = Target().check()
69+
self.assertEqual(
70+
errors,
71+
[
72+
checks.Warning(
73+
"Using Meta.constraints on embedded models is deprecated "
74+
"in favor of using EmbeddedFieldUniqueConstraint in "
75+
"Meta.constraints on the top-level model.",
76+
id="mongodb.fields.embedded_model.W006",
77+
obj=Target,
78+
)
79+
],
80+
)
81+
82+
def test_indexes(self):
83+
class Target(EmbeddedModel):
84+
foo = models.IntegerField()
85+
86+
class Meta:
87+
indexes = [models.Index(fields=["foo"])]
88+
89+
errors = Target().check()
90+
self.assertEqual(
91+
errors,
92+
[
93+
checks.Warning(
94+
"Using Meta.indexes on embedded models is deprecated in "
95+
"favor of using EmbeddedFieldIndex in Meta.indexes on the "
96+
"top-level model.",
97+
id="mongodb.fields.embedded_model.W007",
98+
obj=Target,
99+
)
100+
],
101+
)
102+
103+
def test_unique_together(self):
104+
class Target(EmbeddedModel):
105+
a = models.IntegerField()
106+
b = models.IntegerField()
107+
108+
class Meta:
109+
unique_together = ["a", "b"]
110+
111+
errors = Target().check()
112+
self.assertEqual(
113+
errors,
114+
[
115+
checks.Warning(
116+
"Using Meta.unique_together on embedded models is "
117+
"deprecated in favor of using EmbeddedFieldUniqueConstraint "
118+
"in Meta.constraints on the top-level model.",
119+
id="mongodb.fields.embedded_model.W008",
120+
obj=Target,
121+
)
122+
],
123+
)
124+
125+
19126
class TestManagerMethods(SimpleTestCase):
20127
def test_all(self):
21128
with self.assertRaisesMessage(NotSupportedError, "EmbeddedModels cannot be queried."):

0 commit comments

Comments
 (0)