Works perfectly, thanks :) Tested with a join 4 levels deep too and it made just one query.
I use select_related elsewhere for more generic optimizations but it hadn't occurred to me that django would need the hint once in conjunction with an only() call. Perhaps a patch to ensure that the appropriate select_related call is made in conjunction with an only() would make sense? On Sep 27, 8:28 pm, Alasdair Nicol <alasd...@memset.com> wrote: > Hi John, > > Use select_related [1] to tell Django to 'follow' the foreign key. Try > the following: > > testmodels = > models.ATestModel.objects.all().select_related('other').only('other__name') > print testmodels[0].other.name > > Regards, > Alasdair > > [1]:https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-re... > > On 27/09/11 21:49, John wrote: > > > > > > > > > > > Hey, > > > I'm trying to improve the performance of a Django app, and noticed > > that you can't seem to properly defer fields when making lookups with > > joins. To demonstrate, I set up a test project with the following > > models: > > > class ATestModel(models.Model): > > other = models.ForeignKey('OtherModel') > > > class OtherModel(models.Model): > > name = models.CharField(max_length=32) > > > then, in the Django shell, I set up 10 'ATestModel's and two > > 'OtherModel's properly linked up, and ran the following: > > >>>> from testmodule import models > >>>> testmodels = models.ATestModel.objects.all().only('other__name') > >>>> print testmodels[0].other.name > > Test One > >>>> from django.db import connection > >>>> print '\n\n'.join([x['sql'] for x in connection.queries]) > > SELECT "testmodule_atestmodel"."id", > > "testmodule_atestmodel"."other_id" FROM "testmodule_atestmodel" LIMIT > > 1 > > > SELECT "testmodule_othermodel"."id", "testmodule_othermodel"."name" > > FROM "testmodule_othermodel" WHERE "testmodule_othermodel"."id" = 1 > > > I also re-ran that without the 'only' call: > > >>>> testmodels = models.ATestModel.objects.all() > >>>> print testmodels[0].other.name > > Test One > >>>> print '\n\n'.join([x['sql'] for x in connection.queries[2:]]) > > SELECT "testmodule_atestmodel"."id", > > "testmodule_atestmodel"."other_id" FROM "testmodule_atestmodel" LIMIT > > 1 > > > SELECT "testmodule_othermodel"."id", "testmodule_othermodel"."name" > > FROM "testmodule_othermodel" WHERE "testmodule_othermodel"."id" = 1 > > > The 'only' call does nothing, and two queries are made when one would > > have sufficed (SELECT testmodule_othermodel.name FROM > > testmodule_atestmodel LEFT JOIN testmodule_othermodel ON > > testmodule_atestmodel.id = testmodule_othermodule.id). This raises a > > huge performance penalty for highly normalized schemas and I would > > even go so far as to say it in fact makes it impossible to optimize > > queries with a decently normalized schema. > > > My apologies if someone has brought this up before - I was unable to > > see anything about it in the django tickets or mailing lists. > > -- > Alasdair Nicol > Developer, MEMSET > > mail: alasd...@memset.com > web:http://www.memset.com/ > > Memset Ltd., registration number 4504980. 25 Frederick Sanger Road, > Guildford, Surrey, GU2 7YD, UK. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.