Opened 6 years ago
Closed 6 years ago
#30739 closed Bug (fixed)
OuterRef in exclude() or ~Q() uses wrong model.
| Reported by: | Oskar Persson | Owned by: | Simon Charette |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Simon Charette | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The following test (added to tests/queries/test_qs_combinators) fails when trying to exclude results using OuterRef()
def test_exists_exclude(self):
# filter()
qs = Number.objects.annotate(
foo=Exists(
Item.objects.filter(tags__category_id=OuterRef('pk'))
)
).filter(foo=True)
print(qs) # works
# exclude()
qs = Number.objects.annotate(
foo =Exists(
Item.objects.exclude(tags__category_id=OuterRef('pk'))
)
).filter(foo=True)
print(qs) # crashes
# filter(~Q())
qs = Number.objects.annotate(
foo =Exists(
Item.objects.filter(~Q(tags__category_id=OuterRef('pk')))
)
).filter(foo=True)
print(qs) # crashes
It results in the following error
ValueError: This queryset contains a reference to an outer query and may only be used in a subquery
Change History (4)
comment:1 by , 6 years ago
| Cc: | added |
|---|---|
| Summary: | OuterRef does not work with exclude() or ~Q() → OuterRef in exclude() or ~Q() uses wrong model. |
| Triage Stage: | Unreviewed → Accepted |
| Version: | 2.2 → master |
comment:2 by , 6 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
Note:
See TracTickets
for help on using tickets.
Thanks for the report.
ValueErrorwas fixed in 35431298226165986ad07e91f9d3aca721ff38ec. Provided test fails on master withdjango.db.utils.ProgrammingError: missing FROM-clause entry for table "V0" LINE 1: ...(U1."tag_id" = U2."id") WHERE U2."category_id" = ("V0"."id")...It looks that
OuterRefresolves to"V0"."id"instead of"queries_number"."id"SELECT ... FROM "queries_number" WHERE EXISTS( SELECT ... FROM "queries_item" V0 WHERE NOT (V0."id" IN ( SELECT U1."item_id" FROM "queries_item_tags" U1 INNER JOIN "queries_tag" U2 ON (U1."tag_id" = U2."id") WHERE U2."category_id" = "V0"."id" ))Issue can be reproduce also without annotation
Number.objects.filter(Exists(Item.objects.exclude(tags__category_id=OuterRef('pk'))))