#35677: Unexpected behaviour of Prefetch with queryset filtering on a through
model
-------------------------------------+-------------------------------------
Reporter: David Glenck | Owner: (none)
Type: Bug | Status: new
Component: Database layer | Version: 5.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: Prefetch, | Triage Stage: Accepted
prefetch_related, many-to-many |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by David Glenck):
Hello Simon
thank you for the proposed bugfix. I prepared a test and applied your
patch and it passes with your fix.
However, if I do an annotation after the filter (which I do in my real
world use case). The same happens, when I add another prefetch_related
after the filter.
{{{#!python
prefetched =
Subscriber.objects.filter(pk__in=subscribers).prefetch_related(
Prefetch(
'subscriptions',
queryset=Subscription.objects.filter(status__is_active=True).annotate(active=F('status__is_active')),
to_attr='active_subscriptions'
)
)
}}}
This makes sense, because the last filter/annotation etc. is made sticky,
not the first, like in the case of the many-to-many manager.
Knowing this, for some cases this can be fixed, by moving the additional
annotation before the filter.
But if I do an annotation like this, is seems to fail regardless:
{{{#!python
prefetched =
Subscriber.objects.filter(pk__in=subscribers).prefetch_related(
Prefetch(
'subscriptions',
queryset=Subscription.objects.annotate(active=F('status__is_active')).filter(active=True),
to_attr='active_subscriptions'
)
)
}}}
The many-to-many manager seems to handle this case correctly.
{{{#!python
subscriber1.subscriptions.annotate(active=F('status__is_active')).filter(active=True)
}}}
I have started a branch with the tests here:
https://github.com/django/django/compare/main...pascalfree:django:35677
--
Ticket URL: <https://code.djangoproject.com/ticket/35677#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 view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/010701916155c3de-141c62ca-98ee-4f22-8578-690adf327d45-000000%40eu-central-1.amazonses.com.