Skip to content

fix GenericRelation object_id / target id join type mismatch #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ jobs:
defer
defer_regress
from_db_value
generic_relations
generic_relations_regress
introspection
known_related_objects
lookup
Expand Down
2 changes: 2 additions & 0 deletions django_mongodb/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class DatabaseFeatures(BaseDatabaseFeatures):
"many_to_one.tests.ManyToOneTests.test_selects",
# Incorrect JOIN with GenericRelation gives incorrect results.
"aggregation_regress.tests.AggregationTests.test_aggregation_with_generic_reverse_relation",
"generic_relations.tests.GenericRelationsTests.test_queries_content_type_restriction",
"generic_relations_regress.tests.GenericRelationTests.test_annotate",
# subclasses of BaseDatabaseWrapper may require an is_usable() method
"backends.tests.BackendTestCase.test_is_usable_after_database_disconnects",
# Connection creation doesn't follow the usual Django API.
Expand Down
14 changes: 14 additions & 0 deletions django_mongodb/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from django.conf import settings
from django.db import DataError
from django.db.backends.base.operations import BaseDatabaseOperations
from django.db.models import TextField
from django.db.models.expressions import Combinable
from django.db.models.functions import Cast
from django.utils import timezone
from django.utils.regex_helper import _lazy_re_compile

Expand Down Expand Up @@ -212,6 +214,18 @@ def explain_query_prefix(self, format=None, **options):
super().explain_query_prefix(format, **options)
return validated_options

def prepare_join_on_clause(self, lhs_table, lhs_field, rhs_table, rhs_field):
lhs_expr, rhs_expr = super().prepare_join_on_clause(
lhs_table, lhs_field, rhs_table, rhs_field
)
# If the types are different, cast both to string.
if lhs_field.db_type(self.connection) != rhs_field.db_type(self.connection):
if lhs_field.db_type(self.connection) != "string":
lhs_expr = Cast(lhs_expr, output_field=TextField())
if rhs_field.db_type(self.connection) != "string":
rhs_expr = Cast(rhs_expr, output_field=TextField())
return lhs_expr, rhs_expr

"""Django uses these methods to generate SQL queries before it generates MQL queries."""

# EXTRACT format cannot be passed in parameters.
Expand Down
4 changes: 2 additions & 2 deletions django_mongodb/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ def join(self, compiler, connection):
# Add a join condition for each pair of joining fields.
for lhs, rhs in self.join_fields:
lhs, rhs = connection.ops.prepare_join_on_clause(
self.parent_alias, lhs, self.table_name, rhs
self.parent_alias, lhs, compiler.collection_name, rhs
)
lhs_fields.append(lhs.as_mql(compiler, connection))
# In the lookup stage, the reference to this column doesn't include
# the collection name.
rhs_fields.append(rhs.as_mql(compiler, connection).replace(f"{self.table_name}.", "", 1))
rhs_fields.append(rhs.as_mql(compiler, connection))

parent_template = "parent__field__"
lookup_pipeline = [
Expand Down