#31295: required ModelChoiceField makes duplicate (cursor) queries to the
database
-------------------------------------+-------------------------------------
Reporter: Aurélien Pardon | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Forms | Version: 2.2
Severity: Normal | Resolution: needsinfo
Keywords: Model | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Aurélien Pardon):
Replying to [comment:6 Carlton Gibson]:
> I don't know what else I can say. It's part of the design of
ModelChoiceField that it re-evaluates it's queryset each time it's
iterated.
{{{ModelChoiceField}}} iterates over his {{{ModelChoiceIterator}}} when
rendering its widget (and its options).
{{{ModelChoiceIterator}}} does not necessarily re-evaluates it's queryset
each time it's iterated: sometimes the query is cached (for example when
the query involves a {{{prefetch_related}}}), sometimes it is not cached.
The reason {{{ModelChoiceIterator}}} use, sometimes, {{{.iterator()}}} is
for '''performance''' (less memory usage, see #3534) and because, at the
times, the queryset was evaluated/fetched only once when the the field was
rendered.
After [https://code.djangoproject.com/ticket/27370 Django's Select widget
adds a required="required" attribute, even if created with
empty_label=True], the queryset is evaluated/fetched twice because of the
new {{{.use_required_attribute}}} method.
> See #3534 for example, 13 years ago:
> > ModelChoiceField and ModelMultipleChoiceField cache the output of
their queryset the first time self.choices is accessed. This is bad for
long-running processes, such as mod_python, because the cache gets stale.
Plus, it's bad saving all of those choices in memory. The attached unit
tests illustrate the problem.
> The exact same memory usage considerations were the motivation for the
move to iterator() in #23623. I can't see that being removed.
You said that "correctness trumps performance" but since
[https://code.djangoproject.com/ticket/27370], the usage of
{{{.iterator()}}} in ModelChoiceIterator '''with''' the new
{{{.use_required_attribute}}} when rendering the form leads to invalid
HTML. How is this not a bug?
Moreover, how duplicate requests to the database (the second one is
useless and leads to bug) do not fall under the same performance
considerations of #3534?
I think the solution is to decide to use the required attribute after
having rendered the field options: while iterating the choices/options, we
can check if the first option allows us to use the required attribute.
--
Ticket URL: <https://code.djangoproject.com/ticket/31295#comment:7>
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 view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/065.28842282379cd9e7bff4533a3c4f95b9%40djangoproject.com.