views:

708

answers:

1

Should entry_set be cached with select_related? My DB is still getting calls even after I use select_related. The pertinent 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 "%s x %d" % (a.achievement.name, a.count)

And I'm seeing a big join query at the start, and then individual calls for each achievement. Both for the points and for the name lookup.

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

+1  A: 

Select_related() doesn't work with manytomanyfields. At the moment, this is something that is not planned, but might be a future feature. See http://code.djangoproject.com/ticket/6432

In this case, if you want to make a single query you got two options 1) Make your own SQL, probably won't be pretty or fast. 2) You could also query on the model with the foreignkey. You would be able to use select_related in that case. You stil won't be able to access the modelname_set but with some formatting you would be able to vet the data you need in a single query. None of the options are ideal, but you could get it working at a deacent speed aswell.

googletorp
Bummer. How would you recommend I do that query? SQL by hand?
Paul Tarjan