How to perform a many-to-many filter using ReferenceProperty in Google App Engine?

梦想的初衷 提交于 2019-12-08 07:44:32

问题


This is my model, Players and Clubs. As a Club can have many players and a player can have many clubs (in its carrer), I used a many-to-many relationship:

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

Now, I have a search interface where one can search for all players, and add zero or more restrictions, such as player name, and club where he played. Thus, I have a cascade type of handling this:

  players = player.all()

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

Now, I want to do this:

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

I still think in terms of SQL, and it should be something like a nested clause :

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

How to do it?

I know I could go from the club, that is:

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

but this style discards a previous filter, that could be player names...

Can anybody help me here? Thanks.


回答1:


One common advice in the GAE community is to denormalize your models. This can be useful in this specific situation. You can store the club name in every player entity as a string, in addition to the reference property to the club:

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

This would allow you to easily filter Players by club name.

Obviously, this makes changing club names harder. But the probability of having to change a club name is low.



来源:https://stackoverflow.com/questions/3582674/how-to-perform-a-many-to-many-filter-using-referenceproperty-in-google-app-engin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!