Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.

Commit

Permalink
Merge pull request #51 from dabapps/fix-reverse-m2m
Browse files Browse the repository at this point in the history
For a reverse many-to-many relation we should not (cannot) prefetch the reverse FK
  • Loading branch information
pmg103 authored Feb 21, 2020
2 parents 64ac3d1 + 6f06303 commit 2affb92
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 4 deletions.
4 changes: 3 additions & 1 deletion serialization_spec/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ def prefetch_related(request_user, queryset, model, prefixes, serialization_spec
for rel in model._meta.related_objects
if rel.get_accessor_name() == key
)
only_fields += ['%s_id' % reverse_fk]
has_reverse_fk = any(field.name == reverse_fk for field in relation.related_model._meta.fields)
if has_reverse_fk:
only_fields += ['%s_id' % reverse_fk]
inner_queryset = prefetch_related(request_user, related_model.objects.only(*only_fields), related_model, [], childspec, use_select_related)
if filters:
inner_queryset = inner_queryset.filter(filters).distinct()
Expand Down
8 changes: 6 additions & 2 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,16 @@ def test_single_many_to_many(self):
],
})

def test_single_fk_on_fk(self):
def test_single_fk_on_fk_and_reverse_m2m(self):
with CaptureQueriesContext(connection) as capture:
url = reverse('class-detail', kwargs={'id': str(self.math_class.id)})
response = self.client.get(url)

self.assertJsonEqual(
sorted(query['sql'] for query in capture.captured_queries),
[
"""SELECT "tests_class"."id", "tests_class"."name", "tests_class"."teacher_id", "tests_teacher"."id", "tests_teacher"."created", "tests_teacher"."modified", "tests_teacher"."name", "tests_teacher"."school_id", "tests_school"."id", "tests_school"."created", "tests_school"."modified", "tests_school"."name", "tests_school"."lea_id" FROM "tests_class" INNER JOIN "tests_teacher" ON ("tests_class"."teacher_id" = "tests_teacher"."id") INNER JOIN "tests_school" ON ("tests_teacher"."school_id" = "tests_school"."id") WHERE "tests_class"."id" = '00000000-0000-0000-0000-000000000006'::uuid"""
"""SELECT "tests_class"."id", "tests_class"."name", "tests_class"."teacher_id", "tests_teacher"."id", "tests_teacher"."created", "tests_teacher"."modified", "tests_teacher"."name", "tests_teacher"."school_id", "tests_school"."id", "tests_school"."created", "tests_school"."modified", "tests_school"."name", "tests_school"."lea_id" FROM "tests_class" INNER JOIN "tests_teacher" ON ("tests_class"."teacher_id" = "tests_teacher"."id") INNER JOIN "tests_school" ON ("tests_teacher"."school_id" = "tests_school"."id") WHERE "tests_class"."id" = '00000000-0000-0000-0000-000000000006'::uuid""",
"""SELECT ("tests_student_classes"."class_id") AS "_prefetch_related_val_class_id", "tests_student"."id", "tests_student"."name" FROM "tests_student" INNER JOIN "tests_student_classes" ON ("tests_student"."id" = "tests_student_classes"."student_id") WHERE "tests_student_classes"."class_id" IN ('00000000-0000-0000-0000-000000000006'::uuid)"""
]
)

Expand All @@ -153,6 +154,9 @@ def test_single_fk_on_fk(self):
"name": "Kitteh High"
},
},
'student_set': [
{'name': 'Student 3'}, {'name': 'Student 4'}, {'name': 'Student 5'}, {'name': 'Student 6'}, {'name': 'Student 7'}, {'name': 'Student 8'}, {'name': 'Student 9'},
]
})

def test_single_fk_on_many_to_many(self):
Expand Down
5 changes: 4 additions & 1 deletion tests/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ class ClassDetailView(SerializationSpecMixin, generics.RetrieveAPIView):
'id',
'name'
]}
]}
]},
{'student_set': [
'name',
]},
]


Expand Down

0 comments on commit 2affb92

Please sign in to comment.