В Django, как вы извлекаете данные из дополнительных полей для отношений "многие ко многим" без явного запроса?
Учитывая ситуацию в Django 1.0, где у вас есть дополнительные данные по отношениям "многие-ко-многим" :
class Player(models.Model):
name = models.CharField(max_length=80)
class Team(models.Model):
name = models.CharField(max_length=40)
players = models.ManyToManyField(Player, through='TeamPlayer', related_name='teams')
class TeamPlayer(models.Model):
player = models.ForeignKey(Player)
team = models.ForeignKey(Team)
captain = models.BooleanField()
Отношение "многие ко многим" позволяет вам получить доступ к связанным данным с помощью атрибутов (атрибут "игроки" в объекте "Команда" или использовать атрибут "команды" на объекте Player посредством связанного с ним имени). Когда один из объектов помещается в контекст для шаблона (например, команда, помещенная в контекст для визуализации шаблона, который генерирует список команд), к связанным объектам можно получить доступ (т.е. к игрокам в командах), но как можно можно получить дополнительные данные (например, "капитан" ) вместе с связанными объектами из объекта в контексте (например, с командой) без добавления дополнительных данных в контекст?
Я знаю, что можно получить прямой запрос к таблице промежуточных элементов, чтобы получить дополнительные данные. Например:
TeamPlayer.objects.get(player=790, team=168).captain
Или:
for x in TeamPlayer.objects.filter(team=168):
if x.captain:
print "%s (Captain)" % (x.player.name)
else:
print x.player.name
Выполняя это непосредственно в таблице промежуточных элементов, мне требуется разместить дополнительные данные в контексте шаблона (результат запроса на TeamPlayer), который я пытаюсь избежать, если такая возможность возможна.
Ответы
Ответ 1
Итак, через 15 минут после вопроса, и я нашел свой собственный ответ.
Используя dir(Team)
, я вижу другой сгенерированный атрибут с именем teamplayer_set
(он также существует в Player).
t = Team.objects.get(pk=168)
for x in t.teamplayer_set.all():
if x.captain:
print "%s (Captain)" % (x.player.name)
else:
print x.player.name
Не знаю, как я настроил бы это сгенерированное имя_соединения, но, по крайней мере, я знаю, что могу получить данные из шаблона без добавления дополнительных результатов запроса в контекст.