1
1
from bson import ObjectId , errors
2
- from bson .errors import InvalidId
3
2
from django .core import exceptions
4
3
from django .db .models .fields import Field
5
4
from django .utils .translation import gettext_lazy as _
@@ -14,33 +13,44 @@ class ObjectIdMixin:
14
13
def db_type (self , connection ):
15
14
return "objectId"
16
15
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
+
17
32
def rel_db_type (self , connection ):
18
33
return "objectId"
19
34
20
-
21
- class ObjectIdField (ObjectIdMixin , Field ):
22
- def get_internal_type (self ):
23
- return "ObjectIdField"
24
-
25
35
def to_python (self , value ):
26
- if value is None :
36
+ if value is None or isinstance ( value , int ) :
27
37
return value
28
38
try :
29
39
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
36
49
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"
44
54
45
55
def deconstruct (self ):
46
56
name , path , args , kwargs = super ().deconstruct ()
0 commit comments