Datastore中的一对多关系
这里有一个关于数据存储中一对多关系的不错解释,作者是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.venues
和 somevenue.user
之间的关系。