python - muchos - orm django
En Django, ¿cómo recuperas datos de campos adicionales en relaciones de muchos a muchos sin una consulta explícita para ello? (1)
Entonces, 15 minutos después de hacer la pregunta, y encontré mi propia respuesta.
Utilizando dir(Team)
, puedo ver otro atributo generado llamado teamplayer_set
(también existe en 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
No estoy seguro de cómo personalizaría ese nombre relacionado generado, pero al menos sé que puedo obtener los datos de la plantilla sin agregar resultados de consulta adicionales al contexto.
Dada una situación en Django 1.0 donde tiene datos adicionales sobre una relación Muchos a Muchos :
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()
La relación muchos a muchos le permite acceder a los datos relacionados usando atributos (el atributo "jugadores" en el objeto Team o usando el atributo "teams" en el objeto Player por medio de su nombre relacionado). Cuando uno de los objetos se coloca en un contexto para una plantilla (por ejemplo, un Equipo colocado en un Contexto para representar una plantilla que genera la lista del Equipo), se puede acceder a los objetos relacionados (es decir, los jugadores de los equipos), pero ¿cómo puede los datos adicionales (por ejemplo, ''capitán'') se acceden junto con los objetos relacionados del objeto en contexto (por ejemplo, el Equipo) sin agregar datos adicionales en el contexto?
Sé que es posible consultar directamente en la tabla intermedia para obtener los datos adicionales. Por ejemplo:
TeamPlayer.objects.get(player=790, team=168).captain
O:
for x in TeamPlayer.objects.filter(team=168):
if x.captain:
print "%s (Captain)" % (x.player.name)
else:
print x.player.name
Sin embargo, hacer esto directamente en la tabla intermedia requiere que coloque datos adicionales en el contexto de una plantilla (el resultado de la consulta en TeamPlayer) que estoy tratando de evitar si eso es posible.