python – select_related How to display a model to which another model is linked by ForeignKey

Question:

Django version 1.10

class Game(models.Model):
    game_code = models.CharField(max_length=10)
    home_team = models.ForeignKey(Team, related_name="home_set", default=2, blank=True, null=True)
    away_team = models.ForeignKey(Team, related_name="away_set", default=2, blank=True, null=True)


class GameCoefficient(models.Model):
    game = models.ForeignKey(Game, default=3)
    win_type = models.CharField(choices=win_type, max_length=250,  blank=True, null=True, default="")
    value = models.FloatField(max_length=250, blank=True, null=True, default="")


class BaseView(View):
    data = dict()
    template = "index.html"
    def get(self, request):
        self.data['coefficents_and_game'] = GameCoefficient.objects.all().select_related('game')
        return render_to_response(self.template, self.data)

When rendering, I get the GameCoefficient and ForeignKey GAME, while the template gets the GameCoefficient model and if I do

{% for item in coefficents_and_game %}
     {{item.game}} 
{% endfor %}

in this case, the game code (game_code) is repeated by the number of GameCoefficient and I need to display Game and GameCoefficient in ONE request. But according to the Game table associated with this table GameCoefficient.

{% for game in coefficents_and_game %}
     {{game.game_code}}
     {% for coefficient in game %} 
            {{coefficient.win_type}}
            {{coefficient.value}}
     {% endfor %}
{% endfor %}

By the fact that I read this, you can do one of these operators "select_related" "fetch_reverse_relations" "prefetch_related" well, I could not fully understand the difference between them in order to achieve the result and display an example query in reverse order.

Answer:

select_related must be used for the querset of the model in which the ForeingKey is ForeingKey , i.e. in connection with many to one, on the side of many. prefetch_related works the other way around, on the one side it pulls up all related objects, it can also be used for many-to-many relationships.

Team.objects.prefetch_related('home_set')
Game.objects.select_related('home_team')

Both of these methods can be used to capture the relationships of related models.
In your case, to capture all 3 tables, you can use the following queriset:

self.data['coefficents_and_game'] = GameCoefficient.objects.select_related('game__home_team', 'game__away_team')

This is how you can refer to them in the template:

{% for game in coefficents_and_game %}
     {{ game.win_type }}
     {{ game.value }}
     {% for coefficient in game.game %} 
        {{ coefficient.game_code }}
        # Можно добавить еще один внутренний цикл 
        # по ключам home_team и away_team
     {% endfor %}
{% endfor %}
Scroll to Top