Opened 7 years ago
Closed 7 years ago
#29159 closed Cleanup/optimization (fixed)
ModelChoiceIterator triggers duplicate queries when choices are cast to list
Reported by: | François Freitag | Owned by: | François Freitag |
---|---|---|---|
Component: | Forms | Version: | 1.8 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When there are no prefetch_related()
on ModelChoiceIterator
's queryset, it attempts to use the iterator()
method to avoid loading all choices in memory. (because iterator() and prefetch_related() don't make sense together.)
That results in a duplicate query if the choices have been evaluated before, because calling iterator()
will clone the QuerySet
, resetting its result cache in the process.
class TestModelChoiceField(TestCase): def test_queryset_result_cache_is_reused(self): choice = ChoiceOptionModel.objects.create(name="choice 1") f = ModelChoiceField(ChoiceOptionModel.objects.all()) with self.assertNumQueries(1): self.assertEqual( # list calls both __len__ and __iter__ list(f.choices), [('', '---------'), (choice.pk, str(choice))], )
Fails with:
FAIL: test_queryset_result_cache_is_reused (forms_tests.test_tmp.TestModelChoiceField) ---------------------------------------------------------------------- Traceback (most recent call last): File "django/tests/forms_tests/test_tmp.py", line 19, in test_queryset_result_cache_is_reused [('', '---------'), (choice.pk, str(choice))], File "django/django/test/testcases.py", line 80, in __exit__ '%d. %s' % (i, query['sql']) for i, query in enumerate(self.captured_queries, start=1) AssertionError: 2 != 1 : 2 queries executed, 1 expected Captured queries were: 1. SELECT "forms_tests_choiceoptionmodel"."id", "forms_tests_choiceoptionmodel"."name" FROM "forms_tests_choiceoptionmodel" ORDER BY "forms_tests_choiceoptionmodel"."name" ASC 2. SELECT "forms_tests_choiceoptionmodel"."id", "forms_tests_choiceoptionmodel"."name" FROM "forms_tests_choiceoptionmodel" ORDER BY "forms_tests_choiceoption$odel"."name" ASC
Change History (3)
comment:1 by , 7 years ago
Has patch: | set |
---|
comment:2 by , 7 years ago
Triage Stage: | Unreviewed → Ready for checkin |
---|---|
Type: | Uncategorized → Cleanup/optimization |
Note:
See TracTickets
for help on using tickets.
PR