2015-07-22 4 views
2

Учитывая сценарий, как:Цепной запросы через связанные объекты

from django.db import models 

class Player(models.Model): 
    playername = models.CharField() 

class Team(models): 
    teamname = models.CharField() 

class Members(models): 
    player = models.ForeignKey(Player) 
    team = models.ForeignKey(Team) 

class Division(models): 
    divname = models.CharField() 

class DivisionTeam(models): 
    division = models.ForeignKey(Division) 
    team = models.ForeignKey(Team) 

Как я могу получить список всех различных игроков в дивизионе ид = 5? Я просматриваю выражения Q и F, но я не ищу сложный набор или. Мне интересно, есть ли способ связать несколько типов структур типа object1_set.object2_set.all() или настроить вложенные циклы для создания объекта (который будет передан шаблону через контекст) с конечным циклом типа {% for p in players %} в шаблоне. Идентификатор div передается как переменная запроса.

+0

Uh, 'Player.objects.filter (members__team__divisionteam__divsion__pk = 5)'? Или что-то типа того? Ваша структура db запутывает: P – NightShadeQueen

+0

Я предполагаю, что вы используете слово «отличное», что по какой-то причине у вас есть несколько игроков с тем же именем, и это главный вопрос? Есть ли причина, по которой вы не можете просто использовать [.distinct()] (https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.distinct)? В противном случае я не могу сказать, что вы здесь задаете. – foobarbecue

+0

@NightShadeQueen наследуется (но я сыграл часть), основываясь на существующих базах данных и упрощенном для этого вопроса. Спасибо, я сделаю это. – AMG

ответ

1

Вы можете сделать:

players = Player.objects.filter(members__team__divisionteam__division_id=5).distinct() 

Конечно, как это было предложено в другой ответ, ваши модели могут быть упрощены (с помощью ManyToMany, а не явным образом управлять им)

+0

спасибо. В качестве боковой панели, если заказ немного выключен, можно ожидать, что ошибка «Отношение полей не поддерживает вложенные запросы». Структура трудно изменить, так как некоторые части представляют собой представления другой базы данных; и в некоторых случаях в промежуточных таблицах имеется эффективная информация о дате добавления. Все еще получаю завиток Джанго, но любил его. – AMG

+0

На самом деле, они называются 'through_tables' в django - где вы можете хранить дополнительную информацию в промежуточных таблицах. Рад, что вам нравится django - это потрясающе! – karthikr

+0

Чтение документов, многие из них могут по-прежнему оставаться в пути, но мне нужны дополнительные атрибуты в таблице m2m. что-то вроде http://stackoverflow.com/questions/4443190/djangos-manytomany-relationship-with-additional-fields будет работать для меня и немного упростит запрос.Огромное спасибо всем. – AMG

1

Вы бы сделали все, чтобы упростить ваши модели. Я не думаю, что вам нужно либо из моделей Members или DivisionTeam:

from django.db import models 

class Division(models): 
    divname = models.CharField() 

class Team(models): 
    teamname = models.CharField() 
    division = models.ForeignKey(Division) 

class Player(models.Model): 
    playername = models.CharField() 
    team = models.ManyToManyField(Team) 

Тогда ваш запрос просто:

Player.objects.filter(team__division__pk=5) 

В случае, если Вы ДЕЙСТВИТЕЛЬНО нужны промежуточные модели за комментарии, вы должны использовать through отношения:

# Uses "Salary" as an example intermediate model. 
class Player(models.Model): 
    playername = models.CharField() 
    team = models.ManyToManyField(Team, through="Salary") 

class Salary(models.Model): 
    value = models.IntegerField() 
    player = models.ForeignKey(Player) 
    team = models.ForeignKey(Team) 
+1

Я предполагаю, что OP удалил некоторые поля, чтобы сделать это доступным для чтения. Как «date_started_playing» и «зарплата», и материал, который будет отображаться на модели участника, чтобы игроки могли быть членами нескольких команд. Существует много потенциально веских причин для использования этих промежуточных моделей. – foobarbecue

+0

@foobarbecue хорошая точка - скорректировал мой ответ на счет для этого. – YPCrumble

Смежные вопросы