#29159: ModelChoiceIterator triggers duplicate queries when choices are cast to
list
-------------------------------------+-------------------------------------
Reporter: François | Owner: François Freitag
Freitag |
Type: | Status: assigned
Uncategorized |
Component: Forms | Version: 1.8
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
When there are no `prefetch_related()` on `ModelChoiceIterator`'s
queryset, it attempts to use the `iterator()` method to avoid loading all
choices in memory.
([https://docs.djangoproject.com/en/2.0/ref/models/querysets/#prefetch-
related 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
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/29159>
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 post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/058.cd5424752a3841a0c5ec1990d7f86660%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.