One-to-many relationships in datastore

2019-04-13 13:42发布

There is a nice explanation of 1-to-many relationships in datastore here by Rafe Kaplan. I tried to adapt that to a simpler case of User and Venue. So user can go to many restaurants; and I want to print the user email and the restaurants the user went to:

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)

This prints "club1 club2"

But I want to associate "scott@example.com" with the places he went to; so I want to print something like: "scott@example.com: club1, club2"

Trying

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

gives the error:

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

What is the correct way of doing this? Thanks!

EDIT2 (re: answer by vonPetrushev)

This seems to work:

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)

Displays:

scott@example.com went to:club1club22

EDIT (re: answer by vonPetrushev)

I am a little bit confused.

So I want to write a query like this

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

and display all the venues associated with this user.

It is not clear how User and Venue is connected.

1条回答
Juvenile、少年°
2楼-- · 2019-04-13 14:09

userEmail is not a defined name in the scope of the for loop. What you need is:

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

EDIT: Concerning your edit - if your goal is to make a joined query - you can't, not with the google app datastore. However, you can grab the user like this:

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

and then get the venues like scott.venues. The relation is defined in the line with db.ReferenceProperty, which defines what is someuser.venues and what is somevenue.user.

查看更多
登录 后发表回答