#25496: ModelChoiceField generates extra queries by not respecting
prefetch_related
-------------------------------+--------------------
Reporter: mdentremont | Owner: nobody
Type: Uncategorized | Status: new
Component: Forms | Version:
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------
''Note'': could be worked around if this were resolved:
https://code.djangoproject.com/ticket/22841
When a `ModelChoiceField`'s choices are generated, the queryset's
`prefetch_related` calls are not evaluated, which can lead to 1 query per
choice if the model's `unicode` accesses a related field.
Example models:
{{{#!python
from django.db import models
class RelatedObj(models.Model):
name = models.CharField(max_length=255)
class ObjWithRelated(models.Model):
name = models.CharField(max_length=255)
related = models.ManyToManyField(RelatedObj)
def __unicode__(self):
return '{}: {}'.format(self.name, self.related.count())
}}}
With many models, we can see the following results:
{{{#!python
from django.db import connection
from django.forms import ModelChoiceField
from django.test.utils import CaptureQueriesContext
queryset = ObjWithRelated.objects.prefetch_related('related')
field = ModelChoiceField(queryset)
with CaptureQueriesContext(db.connection) as queries:
list(field.choices)
print 'ModelChoiceField query count: {}'.format(len(queries))
with CaptureQueriesContext(db.connection) as queries:
[str(obj) for obj in queryset]
print 'Regular query count: {}'.format(len(queries))
}}}
This will have the output of:
{{{#!comment
ModelChoiceField query count: <at least 1 query to evaluate the queryset +
1 extra query per ObjWithRelatedModel>
Regular query count: 2
}}}
There are ways to work around this, but ideally there would be a solution
which wouldn't require a workaround. We're using
[https://github.com/edoburu/django-parler django-parler] to translate
models, without the prefetching we get 1 query per dropdown choice, per
dropdown when a translated model is displayed in the django admin.
--
Ticket URL: <https://code.djangoproject.com/ticket/25496>
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/054.249578bce07c9ea6f24a5020b90cdc1a%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.