Query for a ManytoMany Field with Through in Django

django, django-models, many-to-many

Solution

Considering michuk's tip to rename "fee" to "classification":

Default name for Fee objects on Activity model will be fee_set. So in order to get your prices, do this:

for a in Activity.objects.all():
    a.fee_set.all() #gets you all fees for activity

There's one thing though, as you can see you'll end up doing 1 SELECT on each activity object for fees, there are some apps that can help with that, for example, django-batch-select does only 2 queries in this case.

Problem

I have a models in Django that are something like this: ``` class Classification(models.Model): name = models.CharField(choices=class_choices) ... class Activity(models.Model): name = models.CharField(max_length=300) fee = models.ManyToManyField(Classification, through='Fee') ... class Fee(models.Model): activity = models.ForeignKey(Activity) class = models.ForeignKey(Classification) early_fee = models.IntegerField(decimal_places=2, max_digits=10) regular_fee = models.IntegerField(decimal_places=2, max_digits=10) ``` The idea being that there will be a set of fees associated with each Activity and Classification pair. Classification is like Student, Staff, etc. I know that part works right. Then in my application, I query for a set of Activities with: ``` activities = Activity.objects.filter(...) ``` Which returns a list of activities. I need to display in my template that list of Activities with their Fees. Something like this: ``` Activity Name Student Early Price - $4 Student Regular Price - $5 Staff Early Price - $6 Staff Regular Price - $8 ``` But I don't know of an easy way to get this info without a specific get query of the Fees object for each activity/class pair. I hoped this would work: ``` activity.fee.all() ``` But that just returns the Classification Object. Is there a way to get the Fee Object Data for the Pair via the Activities I already queried? Or am I doing this completely wrong?

Original source