#37267: Prefetch can populate a reverse foreign key cache with instances of an
unrelated queryset model
-------------------------------------+-------------------------------------
Reporter: beingfaisal | Type: Bug
Status: new | Component: Database
| layer (models, ORM)
Version: dev | Severity: Normal
Keywords: Prefetch | Triage Stage:
prefetch_related queryset model | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
`Prefetch()` accepts a custom queryset whose model is unrelated to the
model represented by a reverse foreign key lookup. If both models contain
a foreign key with the same name, Django can populate the relationship
cache with instances of the wrong model.
For example:
{{{#!python
class Patient(models.Model):
pass
class ChatAlert(models.Model):
patient = models.ForeignKey(
Patient,
related_name="chatalerts",
on_delete=models.CASCADE,
)
class HealthAlert(models.Model):
patient = models.ForeignKey(
Patient,
related_name="healthalerts",
on_delete=models.CASCADE,
)
}}}
The following prefetch is accepted:
{{{#!python
patient = Patient.objects.create()
health_alert = HealthAlert.objects.create(patient=patient)
patient = Patient.objects.prefetch_related(
Prefetch(
"chatalerts",
queryset=HealthAlert.objects.all(),
)
).get(pk=
patient.pk)
alerts = list(patient.chatalerts.all())
}}}
`Patient.chatalerts` represents the reverse side of
`ChatAlert.patient`, so it should only contain `ChatAlert` instances.
Instead, `alerts` contains the `HealthAlert` instance.
Both models expose `patient` and `patient_id`, so the reverse foreign key
prefetch machinery can filter and group the incompatible queryset without
raising an error. With a different schema, the same invalid configuration
may instead fail later with a less clear field or attribute error.
I expect evaluating the prefetch to raise `ValueError` when the custom
queryset model is incompatible with the relationship model.
A regression test using existing `prefetch_related` test models fails
with:
{{{
AssertionError: ValueError not raised
}}}
Custom querysets using subclasses of the expected relationship model must
remain supported, as established by #36432. Therefore, compatibility
should
be directional: the supplied queryset model may be the expected model or
one of its subclasses, but not an unrelated model.
AI assistance: OpenAI Codex (GPT-5) helped analyze and draft this report.
I manually verified the reproduction.
--
Ticket URL: <
https://code.djangoproject.com/ticket/37267>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.