Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Django Basics Test Time Django TDD

Mike Nedelko
Mike Nedelko
8,991 Points

Confused about performer.song_set.all in performer_detail.html

Hi TeamTreehouse

First let me thank you for such a great course. I really enjoyed it and also liked the final exercise for the Django Basics Course. However, I must admit that I did run into trouble. I was able to resolve it by looking at a forum entry which pointed me to the performer_detail.html. My problem is that although I made it work I am not entirely sure why it is working. My performer_detail.html now looks like this:

{% extends 'base.html' %}

{% block title %}{{ performer.name }}{% endblock %}

{% block content %}
<h2>{{ performer.name }}</h2>
<section>
  {% for each_song in performer.song_set.all %}
    <h3>{{ each_song }}</h3>
  {% endfor %}  
</section>
{% endblock %}

The problem I have is that I don't understand how performer.song_set.all can fetch a set of songs we made in the Song class in models.py? The reason for my confusion is that in class Song(models.Model) we defined performer as performer = performer = models.ForeignKey("Performer", default=1) meaning that there is a 1:1 relationship between Song and Performer. Each song must have a performer. As such I do understand how, if we make an instance of Song, our database would point to the corresponding performer.

What I do struggle with is how our database points from Performer to Songs?. In the view for performer_detail we instantiated Performer and not Song. And because the Performer model odes not point to the Song class, I am struggling to see how we can query this performer.song_set.all which to me is like saying:

"Dear Python. Please give us the set of songs associated with this performer".

While we established in our model how each Performer belongs to a Song (through the ForeignKey function)my mind can't wrap itself around how we know which Song belongs to which Performer. Or am I thinking about this the wrong way?

Any help would be highly appreciated and thank you again for such a great course!

[MOD: added ```jinja formating -cf]

2 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

The short answer is Django magic :smile:

The real answer is Django automatically creates the reverse relationship for you when a ForeignKey is used. The reverse relationship is seen by the _set added to the attribute name. This saves having to edit both models affected by the ForeignKey. It also allows the Performer model code to remain unchanged when other models, such as Song, are connected to it via a ForeignKey.

Another place this is useful is when you are creating models with a ForeignKey to an external class such as User. This way you don't have to edit core Django files to add the reverse relationships from the User model perspective.

Mike Nedelko
Mike Nedelko
8,991 Points

Thank you VERY MUCH! This is really helpful!