Skip to content

Commit 785bcfe

Browse files
committed
Allows int as ObjectIdField
1 parent 6740a0a commit 785bcfe

File tree

3 files changed

+32
-55
lines changed

3 files changed

+32
-55
lines changed

django_mongodb/fields/auto.py

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from bson import ObjectId, errors
2-
from django.core import exceptions
31
from django.db.models.fields import AutoField
42
from django.utils.functional import cached_property
53

@@ -19,40 +17,9 @@ def deconstruct(self):
1917
path = path.replace("django_mongodb.fields.auto", "django_mongodb.fields")
2018
return name, path, args, kwargs
2119

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-
3820
def get_internal_type(self):
3921
return "ObjectIdAutoField"
4022

41-
def to_python(self, value):
42-
if value is None or isinstance(value, int):
43-
return value
44-
try:
45-
return ObjectId(value)
46-
except errors.InvalidId:
47-
try:
48-
return int(value)
49-
except ValueError:
50-
raise exceptions.ValidationError(
51-
self.error_messages["invalid"],
52-
code="invalid",
53-
params={"value": value},
54-
) from None
55-
5623
@cached_property
5724
def validators(self):
5825
# Avoid IntegerField validators inherited from AutoField.

django_mongodb/fields/objectid.py

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from bson import ObjectId, errors
2-
from bson.errors import InvalidId
32
from django.core import exceptions
43
from django.db.models.fields import Field
54
from django.utils.translation import gettext_lazy as _
@@ -14,33 +13,44 @@ class ObjectIdMixin:
1413
def db_type(self, connection):
1514
return "objectId"
1615

16+
def get_prep_value(self, value):
17+
if value is None:
18+
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)):
23+
return value
24+
try:
25+
return ObjectId(value)
26+
except (errors.InvalidId, TypeError) as e:
27+
# A manually assigned integer ID?
28+
if isinstance(value, str) and value.isdigit():
29+
return int(value)
30+
raise ValueError(f"Field '{self.name}' expected an ObjectId but got {value!r}.") from e
31+
1732
def rel_db_type(self, connection):
1833
return "objectId"
1934

20-
21-
class ObjectIdField(ObjectIdMixin, Field):
22-
def get_internal_type(self):
23-
return "ObjectIdField"
24-
2535
def to_python(self, value):
26-
if value is None:
36+
if value is None or isinstance(value, int):
2737
return value
2838
try:
2939
return ObjectId(value)
30-
except (TypeError, InvalidId):
31-
raise exceptions.ValidationError(
32-
self.error_messages["invalid"],
33-
code="invalid",
34-
params={"value": value},
35-
) from None
40+
except (errors.InvalidId, TypeError):
41+
try:
42+
return int(value)
43+
except (ValueError, TypeError):
44+
raise exceptions.ValidationError(
45+
self.error_messages["invalid"],
46+
code="invalid",
47+
params={"value": value},
48+
) from None
3649

37-
def get_prep_value(self, value):
38-
if value is None:
39-
return None
40-
try:
41-
return ObjectId(value)
42-
except (errors.InvalidId, TypeError) as e:
43-
raise ValueError(f"Field '{self.name}' expected an ObjectId but got {value!r}.") from e
50+
51+
class ObjectIdField(ObjectIdMixin, Field):
52+
def get_internal_type(self):
53+
return "ObjectIdField"
4454

4555
def deconstruct(self):
4656
name, path, args, kwargs = super().deconstruct()

tests/model_fields_/test_objectidfield.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ def test_to_python(self):
2727
self.assertIsNone(f.to_python(None))
2828

2929
def test_to_python_invalid_value(self):
30-
for invalid_value in [3, "None", {}, []]:
30+
for invalid_value in ["None", {}, []]:
3131
with self.subTest(invalid_value=invalid_value):
3232
msg = f"['“{invalid_value}” value must be an Object Id.']"
3333
with self.assertRaisesMessage(exceptions.ValidationError, msg):
3434
ObjectIdField().to_python(invalid_value)
3535

3636
def test_get_prep_value_invalud_values(self):
37-
for invalid_value in [3, "None", {}, []]:
37+
for invalid_value in ["None", {}, []]:
3838
with self.subTest(invalid_value=invalid_value):
3939
msg = f"Field '{None}' expected an ObjectId but got {invalid_value!r}."
4040
with self.assertRaisesMessage(ValueError, msg):

0 commit comments

Comments
 (0)