#21703: `exclude` query with `F` object across relationship fails
-------------------------------------+-------------------------------------
Reporter: anonymous | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.6
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Simon Charette):
I confirmed this is fixed by relying on `OuterRef`
{{{
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 7d991b6b84..458ecaa02a 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -19,7 +19,9 @@ from django.core.exceptions import (
from django.db import DEFAULT_DB_ALIAS, NotSupportedError, connections
from django.db.models.aggregates import Count
from django.db.models.constants import LOOKUP_SEP
-from django.db.models.expressions import Col, F, Ref, SimpleCol
+from django.db.models.expressions import (
+ Col, F, OuterRef, Ref, SimpleCol, Subquery,
+)
from django.db.models.fields import Field
from django.db.models.fields.related_lookups import MultiColSource
from django.db.models.lookups import Lookup
@@ -1630,6 +1632,8 @@ class Query:
saner null handling, and is easier for the backend's optimizer to
handle.
"""
+ if isinstance(filter_expr[1], F):
+ filter_expr = (filter_expr[0], OuterRef(filter_expr[1].name))
# Generate the inner query.
query = Query(self.model)
query.add_filter(filter_expr)
@@ -1662,8 +1666,10 @@ class Query:
query.where.add(lookup, AND)
query.external_aliases.add(alias)
+ from django.db import models
+ queryset = models.QuerySet(self.model, query)
condition, needed_inner = self.build_filter(
- ('%s__in' % trimmed_prefix, query),
+ ('%s__in' % trimmed_prefix, Subquery(queryset)),
current_negated=True, branch_negated=True,
can_reuse=can_reuse)
if contains_louter:
or_null_condition, _ = self.build_filter(
}}}
But this makes `Query` depend on `QuerySet` which we want to avoid. I have
always thought `Subquery` wrapping of `QuerySet` instances was unnecessary
and that `OuterRef` ought to be resolved by `Query` anyway so I'll give it
a try.
--
Ticket URL: <https://code.djangoproject.com/ticket/21703#comment:8>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/067.f728587f991c21006097a3167646294f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.