Datastore中的一对多关系

2 投票
1 回答
1740 浏览
提问于 2025-04-16 07:41

这里有一个关于数据存储中一对多关系的不错解释,作者是Rafe Kaplan,你可以在这里找到。我试着把这个解释简化一下,讲讲User(用户)和Venue(场所)之间的关系。也就是说,一个用户可以去很多餐厅;我想打印出用户的邮箱和他去过的餐厅。

class User(db.Model):
    userEmail = db.StringProperty()

class Venue(db.Model):
    user = db.ReferenceProperty(User,
                                   collection_name="venues")
    venue = db.StringProperty()

class OneToMany(webapp.RequestHandler):
    def get(self):
        scott = User(userEmail="scott@example.com")
        scott.put()
        Venue(user=scott,
                     venue="club1").put()
        Venue(user=scott,
                    venue="club2").put()

        for v in scott.venues:
            self.response.out.write(v.venue)

这段代码打印出的是"club1 club2"

但我想把"scott@example.com"和他去过的地方关联起来;所以我想打印出类似于:"scott@example.com: club1, club2"的内容。

我尝试了

for v in scott.venues:
    self.response.out.write(userEmail)
    self.response.out.write(v.venue)

但是出现了错误:

self.response.out.write(userEmail)
NameError: global name 'userEmail' is not defined

那正确的做法是什么呢?谢谢!

编辑2(关于vonPetrushev的回答)

这个方法似乎有效:

query = User.all()
    query.filter("userEmail =", "scott@example.com")
    results=query.fetch(1)
    scott=results[0]
    self.response.out.write("%s went to:" % scott.userEmail)
    for venue in scott.venues:
        self.response.out.write(venue.venue)

显示结果是:

scott@example.com went to: club1 club2

编辑(关于vonPetrushev的回答)

我有点困惑。

我想写一个这样的查询

query = User.all()
query.filter("userEmail =", "scott@example.com")

并显示与这个用户相关的所有场所。

但是User(用户)和Venue(场所)是怎么连接的还不太清楚。

1 个回答

1

userEmail 在这个 for 循环的范围内没有被定义。你需要的是:

for v in scott.venues:
    self.response.out.write(scott.userEmail)
    self.response.out.write(v.venue)

编辑:关于你的编辑 - 如果你的目标是做一个联合查询 - 你是做不到的,尤其是在谷歌的应用数据存储中。不过,你可以这样获取用户:

query = User.all()
query.filter("userEmail =", "scott@example.com")
results=query.fetch(1)
scott=results[0]

然后可以通过 scott.venues 来获取场所。这个关系是在 db.ReferenceProperty 的那一行定义的,它说明了 someuser.venuessomevenue.user 之间的关系。

撰写回答