Как выполнить фильтр «многие ко многим», используя ReferenceProperty в Google App Engine? - PullRequest
1 голос
/ 27 августа 2010

Это моя модель, игроки и клубы.Поскольку в клубе может быть много игроков, а у игрока может быть много клубов (в его каррере), я использовал отношение «многие ко многим»:

class Club(db.Model): 
   name = db.StringProperty()  
   link = db.StringProperty()  

 class Player(db.Model): 
   name = db.StringProperty()  
   link = db.LinkProperty()  

 class ClubHasPlayer(db.Model): 
   club = db.ReferenceProperty(Club, required=True,
      collection_name='club_players')
   player = db.ReferenceProperty(Player, required=True,
      collection_name='player_clubs')
   number = IntegerProperty()

Теперь у меня есть интерфейс поиска, где можно искатьдля всех игроков, и добавьте ноль или более ограничений, таких как имя игрока и клуб, в котором он играл.Таким образом, у меня есть каскадный тип обработки этого:

  players = player.all()

   if filter_by_player_name:
       players.filter("name =",filter_by_player_name)

Теперь я хочу сделать это:

   if filter_by_club_name:
       players.filter(????)

Я все еще думаю с точки зрения SQL, и это должно быть что-токак вложенное предложение:

select * from player where player.name='x' and player.id in (select club_has_player.player_id from club_has_player, club where club_has_player.club_id = club.id and club_name = "Y")

Как это сделать?

Я знаю, что могу выйти из клуба, то есть:

club = Club.filter ("name =", filter_by_club_name) .get () club.club_players

но этот стиль отбрасывает предыдущий фильтр, это могут быть имена игроков ...

Кто-нибудь может мне здесь помочь?Спасибо.

1 Ответ

1 голос
/ 27 августа 2010

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

 class Player(db.Model): 
     name = db.StringProperty()  
     link = db.LinkProperty()
     club = db.ReferenceProperty(club)
     club_name = db.StringProperty()

Это позволит вам легко фильтровать игроков по названию клуба.

Очевидно, это усложняет смену названий клубов. Но вероятность смены названия клуба мала.

...