﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
31295	Avoid Select widget triggering additional query when using ModelChoiceIterator.	Aurélien Pardon	Charles Roelli	"ModelChoiceField use ModelChoiceIterator for its {{{queryset}}}/{{{self.choices}}}, which use {{{.iterator()}}} and doesn't cache the query under some conditions. 

If the field is required, the method use_required_attribute (https://github.com/django/django/blob/master/django/forms/widgets.py#L689) fetch the first choice, making a duplicate query to the database (worse than a useless query, the data may have changed):
{{{#!python
class Select(ChoiceWidget):
    [...]

    def use_required_attribute(self, initial):
        [...]
        first_choice = next(iter(self.choices), None)
}}}


Disabling the use of {{{.iterator()}}} (by adding an arbitrary {{{.prefetch_related}}} for example) leads to no duplicate queries.
https://github.com/django/django/blob/da79ee472d803963dc3ea81ee67767dc06068aac/django/forms/models.py#L1152 :
{{{#!python
class ModelChoiceIterator:
   [...]

    def __iter__(self):
        [...]
        # Can't use iterator() when queryset uses prefetch_related()
        if not queryset._prefetch_related_lookups:
            queryset = queryset.iterator()
}}}


One solution would be to add another test to the previous piece of code :
{{{#!python
        if not queryset._prefetch_related_lookups and not self.field.required:
            queryset = queryset.iterator()
}}}"	Cleanup/optimization	assigned	Forms	2.2	Normal		Model	Aarav Sharma	Accepted	1	0	0	1	0	0
