Skip to content

Commit a277e87

Browse files
committed
edits
1 parent 507a026 commit a277e87

File tree

6 files changed

+85
-49
lines changed

6 files changed

+85
-49
lines changed

django_mongodb/fields/auto.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@ def deconstruct(self):
1919
path = path.replace("django_mongodb.fields.auto", "django_mongodb.fields")
2020
return name, path, args, kwargs
2121

22+
def get_prep_value(self, value):
23+
if value is None:
24+
return None
25+
# Accept int for compatibility with Django's test suite which has many
26+
# instances of manually assigned integer IDs, as well as for things
27+
# like settings.SITE_ID which has a system check requiring an integer.
28+
if isinstance(value, (ObjectId | int)):
29+
return value
30+
try:
31+
return ObjectId(value)
32+
except errors.InvalidId as e:
33+
# A manually assigned integer ID?
34+
if isinstance(value, str) and value.isdigit():
35+
return int(value)
36+
raise ValueError(f"Field '{self.name}' expected an ObjectId but got {value!r}.") from e
37+
2238
def get_internal_type(self):
2339
return "ObjectIdAutoField"
2440

@@ -27,10 +43,10 @@ def to_python(self, value):
2743
return value
2844
try:
2945
return ObjectId(value)
30-
except (errors.InvalidId, TypeError):
46+
except errors.InvalidId:
3147
try:
3248
return int(value)
33-
except (ValueError, TypeError):
49+
except ValueError:
3450
raise exceptions.ValidationError(
3551
self.error_messages["invalid"],
3652
code="invalid",

django_mongodb/fields/objectid.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,19 @@ class ObjectIdMixin:
1313
def db_type(self, connection):
1414
return "objectId"
1515

16+
def rel_db_type(self, connection):
17+
return "objectId"
18+
1619
def get_prep_value(self, value):
1720
if value is None:
1821
return None
19-
# Accept int for compatibility with Django's test suite which has many
20-
# instances of manually assigned integer IDs, as well as for things
21-
# like settings.SITE_ID which has a system check requiring an integer.
22-
if isinstance(value, (ObjectId | int)):
22+
if isinstance(value, ObjectId):
2323
return value
2424
try:
2525
return ObjectId(value)
2626
except (errors.InvalidId, TypeError) as e:
27-
# A manually assigned integer ID?
28-
if isinstance(value, str) and value.isdigit():
29-
return int(value)
3027
raise ValueError(f"Field '{self.name}' expected an ObjectId but got {value!r}.") from e
3128

32-
def rel_db_type(self, connection):
33-
return "objectId"
34-
35-
36-
class ObjectIdField(ObjectIdMixin, Field):
37-
def get_internal_type(self):
38-
return "ObjectIdField"
39-
40-
def deconstruct(self):
41-
name, path, args, kwargs = super().deconstruct()
42-
if path.startswith("django_mongodb.fields.objectid"):
43-
path = path.replace("django_mongodb.fields.objectid", "django_mongodb.fields")
44-
return name, path, args, kwargs
45-
4629
def to_python(self, value):
4730
if value is None:
4831
return value
@@ -54,3 +37,14 @@ def to_python(self, value):
5437
code="invalid",
5538
params={"value": value},
5639
) from None
40+
41+
42+
class ObjectIdField(ObjectIdMixin, Field):
43+
def deconstruct(self):
44+
name, path, args, kwargs = super().deconstruct()
45+
if path.startswith("django_mongodb.fields.objectid"):
46+
path = path.replace("django_mongodb.fields.objectid", "django_mongodb.fields")
47+
return name, path, args, kwargs
48+
49+
def get_internal_type(self):
50+
return "ObjectIdField"

docs/source/fields.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Model ``Field`` reference
2+
=========================
3+
4+
.. module:: django_mongodb.fields
5+
6+
Some MongoDB-specific fields are available in ``django_mongodb.fields``.
7+
8+
``ObjectIdField``
9+
-----------------
10+
11+
.. class:: ObjectIdField
12+
13+
Stores an :class:`~bson.objectid.ObjectId`.

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ django-mongodb 5.0.x documentation
55
:maxdepth: 1
66
:caption: Contents:
77

8+
fields
89
querysets
910

1011
Indices and tables

tests/model_fields_/test_objectidfield.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,40 @@ def test_get_internal_type(self):
1818
self.assertEqual(f.get_internal_type(), "ObjectIdField")
1919

2020
def test_to_python_string(self):
21-
base_string = "1" * 24
22-
expected = ObjectId(base_string)
23-
self.assertEqual(ObjectIdField().to_python(base_string), expected)
21+
value = "1" * 24
22+
self.assertEqual(ObjectIdField().to_python(value), ObjectId(value))
2423

2524
def test_to_python_objectid(self):
26-
base_string = "1" * 24
27-
expected = ObjectId(base_string)
28-
self.assertEqual(ObjectIdField().to_python(expected), expected)
25+
value = ObjectId("1" * 24)
26+
self.assertEqual(ObjectIdField().to_python(value), value)
2927

30-
def test_to_python_null_value(self):
28+
def test_to_python_null(self):
3129
self.assertIsNone(ObjectIdField().to_python(None))
3230

3331
def test_to_python_invalid_value(self):
34-
for invalid_value in ["None", {}, []]:
32+
f = ObjectIdField()
33+
for invalid_value in ["None", {}, [], 123]:
3534
with self.subTest(invalid_value=invalid_value):
3635
msg = f"['“{invalid_value}” value must be an Object Id.']"
3736
with self.assertRaisesMessage(exceptions.ValidationError, msg):
38-
ObjectIdField().to_python(invalid_value)
37+
f.to_python(invalid_value)
38+
39+
def test_get_prep_value_string(self):
40+
value = "1" * 24
41+
self.assertEqual(ObjectIdField().get_prep_value(value), ObjectId(value))
42+
43+
def test_get_prep_value_objectid(self):
44+
value = ObjectId("1" * 24)
45+
self.assertEqual(ObjectIdField().get_prep_value(value), value)
3946

40-
def test_get_prep_value_invalud_values(self):
41-
for invalid_value in ["None", {}, []]:
47+
def test_get_prep_valuen_null(self):
48+
self.assertIsNone(ObjectIdField().to_python(None))
49+
50+
def test_get_prep_value_invalid_values(self):
51+
f = ObjectIdField()
52+
f.name = "test"
53+
for invalid_value in ["None", {}, [], 123]:
4254
with self.subTest(invalid_value=invalid_value):
43-
msg = f"Field '{None}' expected an ObjectId but got {invalid_value!r}."
55+
msg = f"Field 'test' expected an ObjectId but got {invalid_value!r}."
4456
with self.assertRaisesMessage(ValueError, msg):
45-
ObjectIdField().get_prep_value(invalid_value)
57+
f.get_prep_value(invalid_value)

tests/queries_/test_objectid.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from .models import Tag
55

66

7-
class QueriesFilterByObjectId(TestCase):
7+
class ObjectIdTests(TestCase):
88
@classmethod
99
def setUpTestData(cls):
1010
cls.group_id_str_1 = "1" * 24
@@ -19,72 +19,72 @@ def setUpTestData(cls):
1919
cls.t5 = Tag.objects.create(name="t5", parent=cls.t3)
2020

2121
def test_filter_group_id_is_null_false(self):
22-
"""Filter objects where group_id is not null"""
22+
"""Filter objects where group_id is not null."""
2323
qs = Tag.objects.filter(group_id__isnull=False).order_by("name")
2424
self.assertSequenceEqual(qs, [self.t3, self.t4])
2525

2626
def test_filter_group_id_is_null_true(self):
27-
"""Filter objects where group_id is null"""
27+
"""Filter objects where group_id is null."""
2828
qs = Tag.objects.filter(group_id__isnull=True).order_by("name")
2929
self.assertSequenceEqual(qs, [self.t1, self.t2, self.t5])
3030

3131
def test_filter_group_id_equal_str(self):
32-
"""Filter by group_id with a specific string value"""
32+
"""Filter by group_id with a specific string value."""
3333
qs = Tag.objects.filter(group_id=self.group_id_str_1).order_by("name")
3434
self.assertSequenceEqual(qs, [self.t3])
3535

3636
def test_filter_group_id_equal_obj(self):
37-
"""Filter by group_id with a specific ObjectId value"""
37+
"""Filter by group_id with a specific ObjectId value."""
3838
qs = Tag.objects.filter(group_id=self.group_id_obj_1).order_by("name")
3939
self.assertSequenceEqual(qs, [self.t3])
4040

4141
def test_filter_group_id_in_str_values(self):
42-
"""Filter by group_id with string values in a list"""
42+
"""Filter by group_id with string values in a list."""
4343
qs = Tag.objects.filter(group_id__in=[self.group_id_str_1, self.group_id_str_2]).order_by(
4444
"name"
4545
)
4646
self.assertSequenceEqual(qs, [self.t3, self.t4])
4747

4848
def test_filter_group_id_in_obj_values(self):
49-
"""Filter by group_id with ObjectId values in a list"""
49+
"""Filter by group_id with ObjectId values in a list."""
5050
qs = Tag.objects.filter(group_id__in=[self.group_id_obj_1, self.group_id_obj_2]).order_by(
5151
"name"
5252
)
5353
self.assertSequenceEqual(qs, [self.t3, self.t4])
5454

5555
def test_filter_group_id_equal_subquery(self):
56-
"""Filter by group_id using a subquery"""
56+
"""Filter by group_id using a subquery."""
5757
subquery = Tag.objects.filter(name="t3").values("group_id")
5858
qs = Tag.objects.filter(group_id__in=subquery).order_by("name")
5959
self.assertSequenceEqual(qs, [self.t3])
6060

6161
def test_filter_group_id_in_subquery(self):
62-
"""Filter by group_id using a subquery with multiple values"""
62+
"""Filter by group_id using a subquery with multiple values."""
6363
subquery = Tag.objects.filter(name__in=["t3", "t4"]).values("group_id")
6464
qs = Tag.objects.filter(group_id__in=subquery).order_by("name")
6565
self.assertSequenceEqual(qs, [self.t3, self.t4])
6666

6767
def test_filter_parent_by_children_values_str(self):
68-
"""Query to select parents of children with specific string group_id"""
68+
"""Query to select parents of children with specific string group_id."""
6969
child_ids = Tag.objects.filter(group_id=self.group_id_str_1).values_list("id", flat=True)
7070
parent_qs = Tag.objects.filter(children__id__in=child_ids).distinct().order_by("name")
7171
self.assertSequenceEqual(parent_qs, [self.t1])
7272

7373
def test_filter_parent_by_children_values_obj(self):
74-
"""Query to select parents of children with specific ObjectId group_id"""
74+
"""Query to select parents of children with specific ObjectId group_id."""
7575
child_ids = Tag.objects.filter(group_id=self.group_id_obj_1).values_list("id", flat=True)
7676
parent_qs = Tag.objects.filter(children__id__in=child_ids).distinct().order_by("name")
7777
self.assertSequenceEqual(parent_qs, [self.t1])
7878

7979
def test_filter_group_id_union_with_str(self):
80-
"""Combine queries using union with string values"""
80+
"""Combine queries using union with string values."""
8181
qs_a = Tag.objects.filter(group_id=self.group_id_str_1)
8282
qs_b = Tag.objects.filter(group_id=self.group_id_str_2)
8383
union_qs = qs_a.union(qs_b).order_by("name")
8484
self.assertSequenceEqual(union_qs, [self.t3, self.t4])
8585

8686
def test_filter_group_id_union_with_obj(self):
87-
"""Combine queries using union with ObjectId values"""
87+
"""Combine queries using union with ObjectId values."""
8888
qs_a = Tag.objects.filter(group_id=self.group_id_obj_1)
8989
qs_b = Tag.objects.filter(group_id=self.group_id_obj_2)
9090
union_qs = qs_a.union(qs_b).order_by("name")

0 commit comments

Comments
 (0)