Select_related Как вывести модель к которой привязана другая модель по ForeignKey

Kamran XIDIROV

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)

При рендеринге я получаю GameCoefficient и ForeignKey GAME при этом template получает по GameCoefficient модели и если делать

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

в этом случае код игр(game_code) повторяется по количеству GameCoefficient а мне нужно ОДНИМ запросом вывести Game и GameCoefficient. Но по Game таблице связанные с этой таблицей GameCoefficient.

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

По тому что читал это можно сделать одним из этих операторов "select_related" "fetch_reverse_relations" "prefetch_related" ну до конца не смог понять разницу между ними, что бы добиться результата и вывести в обратном порядке примера запроса.

1 ответ

Kamran XIDIROV

select_related нужно использовать у кверисета модели, в которой указан ForeingKey, т.е. при связи многие к одному, на стороне многих. prefetch_related работает наоборот, на стороне одного подтягивает все связанные объекты, так же его можно использовать при связи многие ко многим.

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

Оба этих метода можно использовать, для захвата связей связанных моделей. В вашем случае, чтобы захватить все 3 таблицы можно использовать такой кверисет:

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

Так к ним можно обращаться в шаблоне:

{% 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 %}

licensed under cc by-sa 3.0 with attribution.