#36373: select_related() doesn't work when targeting composite primary keys
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Type: Bug
Status: new | Component: Database
| layer (models, ORM)
Version: 5.2 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
The [
https://docs.djangoproject.com/en/5.2/topics/composite-primary-key
/#composite-primary-keys-and-relations suggested workaround] until #35956
implements foreign keys to models with composite primary keys is to use
`ForeignObject`, but it causes failures in `select_related()`. (Of note:
`prefetch_related()` works fine.)
{{{#!diff
diff --git a/tests/composite_pk/tests.py b/tests/composite_pk/tests.py
index 5dea23c9f2..068030bd18 100644
--- a/tests/composite_pk/tests.py
+++ b/tests/composite_pk/tests.py
@@ -184,6 +184,11 @@ class CompositePKTests(TestCase):
with self.assertNumQueries(1):
self.assertEqual(user.email, self.user.email)
+ def test_select_related(self):
+ with self.assertNumQueries(1):
+ for comment in Comment.objects.select_related():
+ comment.user
+
def test_model_forms(self):
fields = ["tenant", "id", "user_id", "text", "integer"]
self.assertEqual(list(CommentForm.base_fields), fields)
}}}
{{{
======================================================================
ERROR: test_select_related
(composite_pk.tests.CompositePKTests.test_select_related)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/.../django/tests/composite_pk/tests.py", line 189, in
test_select_related
for comment in Comment.objects.select_related():
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/Users/.../django/django/db/models/query.py", line 403, in
__iter__
self._fetch_all()
~~~~~~~~~~~~~~~^^
File "/Users/.../django/django/db/models/query.py", line 1966, in
_fetch_all
self._result_cache = list(self._iterable_class(self))
~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/.../django/django/db/models/query.py", line 107, in
__iter__
related_populators = get_related_populators(klass_info, select, db,
fetch_mode)
File "/Users/.../django/django/db/models/query.py", line 2742, in
get_related_populators
rel_cls = RelatedPopulator(rel_klass_info, select, db, fetch_mode)
File "/Users/.../django/django/db/models/query.py", line 2710, in
__init__
self.pk_idx = self.init_list.index(self.model_cls._meta.pk.attname)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: 'pk' is not in list
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/36373>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.