Reputation: 273
Trying to model a many-to-many relationship with ndb. Can anyone point to a good example of how to do this?
At here is an example of what I have at the moment:
class Person(ndb.Model):
guilds = ndb.KeyProperty(kind="Guild", repeated=True)
class Guild(ndb.Model)
members = ndb.KeyProperty(kind="Person", repeated=True)
def add_person(self, person):
self.members.append(person.key)
self.put()
person.guilds.append(self.key)
person.put()
Is this the correct way to go about it? I have had a good look around but can't seem to find any good documentation on the subject.
In the datastore viewer, I can see this relationship being stored as a list of Keys, which I expect.
However, when I try to use them in the Person class methods like this:
for guild in self.guilds:
I get:
TypeError: 'KeyProperty' object is not iterable
Upvotes: 8
Views: 1932
Reputation: 695
No. That is not the correct way to go about it.
You can model a many-to-many relationship with only one repeated property:
class Person(ndb.Model):
guilds = ndb.KeyProperty(kind="Guild", repeated=True)
class Guild(ndb.Model):
@property
def members(self):
return Person.query().filter(Person.guilds == self.key)
def add_person(self, person):
person.guilds.append(self.key)
person.put()
or viceversa with:
class Person(ndb.Model):
@property
def guilds(self):
return Guild.query().filter(Guild.members == self.key)
class Guild(ndb.Model):
members = ndb.KeyProperty(kind="Person", repeated=True)
def add_person(self, person):
self.members.append(person.key)
self.put()
The direction of the relationship depends on many factors (your business model, number of guilds per person, number of members per guild, etc.)
Upvotes: 14