2009-01-15 69 views
5

我正在使用谷歌应用程序引擎,并且无法编写查询来过滤ReferenceProperties。使用ReferenceProperties过滤模型

例如。

class Group(db.Model): 
    name = db.StringProperty(required=True) 
    creator = db.ReferenceProperty(User) 

class GroupMember(db.Model): 
    group = db.ReferenceProperty(Group) 
    user = db.ReferenceProperty(User) 

我试图写这样的事情:

members = models.GroupMember.all().filter('group.name =', group_name) 

和不工作的各种其他的东西。希望有人能给我一个正确的方向...

回答

4

如果您想要获得组的成员,那么ReferenceProperties具有内置的组件。

class GroupMember(db.Model): 
    group = db.ReferenceProperty(Group, collection_name="groupMembers") 
    user = db.ReferenceProperty(User, collection_name="groupMembers") 

然后,你可以写:

# get the group entity somehow 
group = Group.get(group_key)  
# do something with the members, such as list the nicknames 
nicknames = [x.user.nickname for x in group.groupMembers] 
1

这将需要一个连接,这是不可能在App Engine中。如果您想过滤另一个模型的属性,则需要在要查询的模型中包含该属性。

1

这将导致两个数据存储点击,但应该工作。如果你使用memcache不应该是一个问题。

group = models.Group.all().filter("name =", group_name).get() 
members = models.GroupMember.all().filter('group =', group) 
5

如果您的组是唯一命名的,那么您的“group.name”是组实体的唯一标识符。

这意味着你可以这样写:

members = models.GroupMember.all().filter(
    "group =",model.Group.gql("WHERE name=:1", group_name).get() 
    ) 

虽然你只需要做的,如果你还没有在堆栈躺在附近的某个地方组实体。

谷歌有关appengine的多对多的文章是here

0

使用,你在你的问题中定义的模型,假设你想列出一个名为“太空猴子”组的所有成员。

mygroup = Group.gql("WHERE name = :1",'Space monkeys') 

for group_member in mygroup.groupmember_set: 
    print 'group members name is: %s' % (group_member.user.name) 

的“groupmember_set”被称为“隐式集合属性”,是非常有用的。您可以通过使用collection_name关键字参数覆盖缺省名称来随心所欲地调用它。例如,请参阅Thomas L Holaday的答案。

这一切都在Rafe Kapla的一篇很好的论文中解释过:Modeling Entity Relationships