2010-08-27 3 views
1

Ceci est mon modèle, les joueurs et les clubs. En tant que club peut avoir de nombreux joueurs et un joueur peut avoir de nombreux clubs (dans son carrer), j'ai utilisé plusieurs-à-plusieurs:Comment effectuer un filtre plusieurs-à-plusieurs à l'aide de ReferenceProperty dans Google App Engine?

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() 

Maintenant, j'ai une interface de recherche où l'on peut rechercher tous joueurs, et ajouter zéro ou plus de restrictions, telles que le nom du joueur, et le club où il a joué. Ainsi, j'ai un type de cascade de manipulation ceci:

players = player.all() 

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

Maintenant, je veux faire:

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

Je pense toujours en termes de SQL, et il devrait être quelque chose comme une clause imbriquée :

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") 

Comment faire?

Je sais que je pourrais aller du club, qui est:

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

mais ce style se défausse d'une filtre précédent, qui pourrait être des noms de joueur ...

Quelqu'un peut-il m'aider ici? Merci.

Répondre

1

Un conseil commun dans la communauté GAE est de dénormaliser vos modèles. Cela peut être utile dans cette situation spécifique. Vous pouvez enregistrer le nom du club dans chaque entité joueur comme une chaîne, en plus de la propriété de référence au club:

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

Cela vous permettra de facilement filtrer par nom Les joueurs du club.

De toute évidence, cela rend plus difficile le changement de nom de club. Mais la probabilité d'avoir à changer de nom de club est faible.

+0

+1 Vous devez dénormaliser pour utiliser l'évolutivité qu'offre le moteur de l'application. –

+0

Yup, dénormaliser. C'est la réponse, c'est ce que j'ai fait. Merci. –

+0

Acceptez la dénormalisation, mais cet exemple ne fonctionnera pas. Il ne permet qu'une référence de club par joueur, mais le demandeur souhaite une relation plusieurs-à-plusieurs. – Yarin