#30124: QuerySet.only() on reverse many-to-one relationship causes extra database queries -------------------------------------+------------------------------------- Reporter: Beda | Owner: nobody Kosata | Type: Bug | Status: new Component: Database | Version: 2.1 layer (models, ORM) | 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 | -------------------------------------+------------------------------------- Using the following example models:
{{{ class WorkSet(models.Model): name = models.TextField(blank=True) class Work(models.Model): name = models.TextField(blank=True) work_set = models.ForeignKey(WorkSet, on_delete=models.CASCADE, related_name='works') extra_data = JSONField(default=dict, blank=True) }}} when I iterate over the Works related to a WorkSet {{{ ws }}} like this: {{{ for work in ws.works.all().only('name'): print(work.name) }}} Not only one query is made to the database, but 1+N where N is the number of Works related to the WorkSet. In {{{ connection.queries }}} these queries look like this {{{ 'SELECT "test_work"."id", "test_work"."work_set_id" FROM "test_work" WHERE "test_work"."id" = 677931' }}} etc. That is - the ORM refetches the {{{ work_set_id }}} for each of the Works iterated over. If I change the loop to explicitly include {{{ work_set_id }}}, only one query is run: {{{ for work in ws.works.all().only('name', 'work_set_id'): print(work.name) }}} While this behavior makes some sense, I find it quite unexpected and a potential cause of nasty performance 'leaks'. It think that either the documentation should explicitly mention this case and how to work around it or better the ORM should automatically add the relationship key into the fetched fields. Please let me know if anything is unclear about this issue and if there is anything I can improve. -- Ticket URL: <https://code.djangoproject.com/ticket/30124> 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 django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/049.39e8389288bf4cf84a8905996c8e9ce6%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.