Django: select_related with entry_set

Should entry_set be cached with select_related? My DB is still ringing even after I use select_related. Relevant Sections

class Alias(models.Model): achievements = models.ManyToManyField('Achievement', through='Achiever') def points(self) : points = 0 for a in self.achiever_set.all() : points += a.achievement.points * a.count return points class Achievement(models.Model): name = models.CharField(max_length=100) points = models.IntegerField(default=1) class Achiever(models.Model): achievement = models.ForeignKey(Achievement) alias = models.ForeignKey(Alias) count = models.IntegerField(default=1) aliases = Alias.objects.all().select_related() for alias in aliases : print "points : %s" % alias.points() for a in alias.achiever_set.all()[:5] : print "%sx %d" % (a.achievement.name, a.count) 

And I see a big connection request at the beginning, and then individual calls for each achievement. Both for points, and for search of a name.

Is this a mistake, or am I doing something wrong?

+4
source share
3 answers

Select_related () does not work with manytomanyfields. At the moment, this is what is not planned, but may be a future function. See http://code.djangoproject.com/ticket/6432

In this case, if you want to make one query, you have two options 1) Create your own SQL, probably will not be beautiful or fast. 2) You can also request a model using a foreign key. You could use select_related in this case. You will not be able to access modelname_set, but with some formatting, you will be able to verify the data you need in a single request. None of the options are perfect, but you can make it work at the proper speed.

+4
source

With Django 1.4, you can use prefetch_related, which will work for ManyToMany relationships:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related

+4
source

In Django 1.3, you can use Queryset.values ​​() and do something like:

 Alias.objects[.filter().exclude() etc.].values('achievements__name', 'achievement__points') 

Only drwaback is what you get QuerySetList instead of QuerySet. But this can simply be overcome by passing all the necessary fields into values ​​() - you must change your perception;)

This can save you from multiple query requests ...

Details can be found here in the django docs: http://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values

0
source

All Articles