如何在Google App Engine中使用ReferenceProperty执行多对多过滤器? [英] How to perform a many-to-many filter using ReferenceProperty in Google App Engine?

查看:121
本文介绍了如何在Google App Engine中使用ReferenceProperty执行多对多过滤器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的模特,球员和俱乐部。作为一个俱乐部可以有很多球员和一个球员可以有很多俱乐部(在其carrer),我使用了一个多对多的关系:

  class Club(db.Model):
name = db.StringProperty()$ b $ link = db.StringProperty()
$ b $ class Player(db.Model):
name = db.StringProperty()
link = db.LinkProperty()
$ b $ 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()

如果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(从club_has_player选择club_has_player.player_id,其中club_has_player.club_id = club.id和club_name =Y)

如何操作?



我知道我可以去俱乐部,那就是:

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



但这种风格丢弃了之前的过滤器,可能是玩家的名字......



有人可以帮我吗?感谢。

解决方案

GAE社区的一个常见建议是对模型进行非规范化。这在这个特定的情况下可能很有用。除了对俱乐部的引用属性之外,您还可以将每个球员实体的俱乐部名称存储为一个字符串:

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

这可让您轻松过滤球员名称。



显然,这使得更改俱乐部名称更困难。但不得不改变俱乐部名称的可能性很低。

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.

解决方案

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.

这篇关于如何在Google App Engine中使用ReferenceProperty执行多对多过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆