#17439: prefetch_related issues extra queries for optional OneToOneFields ----------------------------------------------+-------------------- Reporter: gwahl@… | Owner: nobody Type: Bug | Status: new Component: Database layer (models, ORM) | Version: SVN Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 0 Easy pickings: 0 | UI/UX: 0 ----------------------------------------------+-------------------- Given these models:
{{{#!python class ModelA(models.Model): pass class ModelB(models.Model): a = models.OneToOneField(ModelA, related_name='b') }}} I expect that after doing `ModelA.objects.prefetch_related('b')`, the `b` attribute of all the results can be accessed without causing another query. This is not the case: {{{ >>> from app.models import * >>> a = ModelA.objects.all()[0] SELECT "app_modela"."id" FROM "app_modela" LIMIT 1 >>> a.b # should do a query, prefetch_related was not used SELECT "app_modelb"."id", "app_modelb"."a_id" FROM "app_modelb" WHERE "app_modelb"."a_id" = 1 Traceback (most recent call last): File "<console>", line 1, in <module> File "/srv/python- environments/egg/src/django/django/db/models/fields/related.py", line 255, in __get__ rel_obj = self.get_query_set(instance=instance).get(**params) File "/srv/python- environments/egg/src/django/django/db/models/query.py", line 361, in get % self.model._meta.object_name) DoesNotExist: ModelB matching query does not exist. ## it did another query, and raised DoesNotExist, just like expected. >>> a = ModelA.objects.all().prefetch_related('b')[0] SELECT "app_modela"."id" FROM "app_modela" LIMIT 1 SELECT "app_modelb"."id", "app_modelb"."a_id" FROM "app_modelb" >>> a.b # should not do a query, we already got all the `b`s SELECT "app_modelb"."id", "app_modelb"."a_id" FROM "app_modelb" WHERE "app_modelb"."a_id" = 1 Traceback (most recent call last): File "<console>", line 1, in <module> File "/srv/python- environments/egg/src/django/django/db/models/fields/related.py", line 255, in __get__ rel_obj = self.get_query_set(instance=instance).get(**params) File "/srv/python- environments/egg/src/django/django/db/models/query.py", line 361, in get % self.model._meta.object_name) DoesNotExist: ModelB matching query does not exist. ## Another query was issued even though we know it can not return any results >>> }}} Any possible `b` object was already fetched by `prefetch_related`, but accessing the property causes another query anyway. Note that this is only the case when `a` does not have a `b` object, the extra query does not happen if there was a `b` fetched by `prefetch_related`. -- Ticket URL: <https://code.djangoproject.com/ticket/17439> 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 post to this group, send email to django-updates@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.