Skip to content

Commit ce2ff89

Browse files
committed
Add support for GenericForeignKey and GenericRelation.
1 parent 0415f2c commit ce2ff89

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

.github/workflows/test-python.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ jobs:
8383
defer
8484
defer_regress
8585
from_db_value
86+
generic_relations
8687
introspection
8788
known_related_objects
8889
lookup

django_mongodb/features.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
7979
"many_to_one.tests.ManyToOneTests.test_selects",
8080
# Incorrect JOIN with GenericRelation gives incorrect results.
8181
"aggregation_regress.tests.AggregationTests.test_aggregation_with_generic_reverse_relation",
82+
"generic_relations.tests.GenericRelationsTests.test_queries_content_type_restriction",
8283
# subclasses of BaseDatabaseWrapper may require an is_usable() method
8384
"backends.tests.BackendTestCase.test_is_usable_after_database_disconnects",
8485
# Connection creation doesn't follow the usual Django API.
@@ -247,6 +248,7 @@ def django_test_expected_failures(self):
247248
},
248249
"Test assumes integer primary key.": {
249250
"db_functions.comparison.test_cast.CastTests.test_cast_to_integer_foreign_key",
251+
"generic_relations.tests.GenericRelationsTests.test_cache_invalidation_for_content_type_id",
250252
"model_fields.test_foreignkey.ForeignKeyTests.test_to_python",
251253
"queries.test_qs_combinators.QuerySetSetOperationTests.test_order_raises_on_non_selected_column",
252254
},

django_mongodb/fields/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from .auto import ObjectIdAutoField
22
from .duration import register_duration_field
33
from .json import register_json_field
4+
from .object_id import ObjectIdField
45

5-
__all__ = ["register_fields", "ObjectIdAutoField"]
6+
__all__ = ["register_fields", "ObjectIdAutoField", "ObjectIdField"]
67

78

89
def register_fields():

django_mongodb/fields/object_id.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from bson import ObjectId, errors
2+
from django.db.models.fields import Field
3+
from django.utils.translation import gettext_lazy as _
4+
5+
6+
class ObjectIdField(Field):
7+
description = _("Object Id")
8+
9+
def get_internal_type(self):
10+
return "ObjectIdField"
11+
12+
def db_type(self, connection):
13+
return "ObjectId"
14+
15+
def get_prep_value(self, value):
16+
value = super().get_prep_value(value)
17+
return self.to_python(value)
18+
19+
def to_python(self, value):
20+
if value is None:
21+
return value
22+
if isinstance(value, ObjectId | int):
23+
return value
24+
try:
25+
return ObjectId(value)
26+
except errors.InvalidId 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

0 commit comments

Comments
 (0)