Reputation: 21
I'm just starting out with AppEngine and using the endpoints_proto_datastore library. My problem: when I attempt to list all the PlaylistItems for a particular Playlist, the 'playlist' parameter in the query path seems to be ignored. I just retrieve all the PlaylistItems from all Playlists.
What am I doing wrong? I haven't been able to find any examples with two models, where the models are related by KeyProperty and queried via the path-element. I also don't understand why I don't see PlaylistItem.playlist in the datastore (unless it is part of the key).
These are the relevant Models and methods:
from endpoints_proto_datastore.ndb import EndpointsAliasProperty
from endpoints_proto_datastore.ndb import EndpointsModel
class Playlist(EndpointsModel):
"""Models an individual Playlist."""
# fixed order
_message_fields_schema = ('id', 'user', 'title', 'private', 'created')
# actual stored information
user = ndb.StringProperty(required=True, indexed=True)
title = ndb.StringProperty(required=True, indexed=False)
private = ndb.BooleanProperty(required=False, default=True, indexed=False)
created = ndb.DateTimeProperty(required=False, auto_now_add=True, indexed=False)
class PlaylistItem(EndpointsModel):
"""Models a playlist item (appid)"""
# fixed order
_message_fields_schema = ('appid', 'inserted')
# actual stored information
appid = ndb.StringProperty(required=True, indexed=False)
inserted = ndb.DateTimeProperty(required=False, auto_now_add=True, indexed=True)
playlist = ndb.KeyProperty(required=True, kind=Playlist, indexed=True)
def PlaylistSet(self, value):
playlist = ndb.Key(Playlist, value)
@EndpointsAliasProperty(setter=PlaylistSet, required=True)
def playlist(self):
playlist
and the relevant methods:
@PlaylistItem.method(path='playlist/{playlist}/items', http_method='POST', name='playlist.items.put',
request_fields=('playlist','appid'))
def PlaylistItemPut(self, PlaylistItem):
PlaylistItem.put()
return PlaylistItem
@PlaylistItem.query_method(path='playlist/{playlist}/items', name='playlist.items.list',
query_fields=('playlist',),)
def PlaylistItemList(self, query):
return query # problem, I just retrieve all PlaylistItems
Upvotes: 1
Views: 178
Reputation: 21
I changed the code based on the suggestions from Alex. It seems the most important bug I had was not using self.playlist from the PlaylistSet method. Afterwards I had the naming conflic that Alex pointed out. Below is the working code after all changes:
class PlaylistItem(EndpointsModel):
"""Models a playlist item (appid)"""
# fixed order
_message_fields_schema = ('appid', 'inserted')
# actual stored information
appid = ndb.StringProperty(required=True, indexed=False)
inserted = ndb.DateTimeProperty(required=False, auto_now_add=True, indexed=True)
playlist = ndb.KeyProperty(required=True, kind=Playlist, indexed=True)
def PlaylistSet(self, value):
self.playlist = ndb.Key(Playlist, value) # FIX: MUST use self.playlist here!
@EndpointsAliasProperty(setter=PlaylistSet, required=True)
def myplaylist(self): # renamed the method
return playlist # return the playlist
Also updated the Playlist API methods to use the new myplaylist name:
@PlaylistItem.method(path='playlist/{myplaylist}/items', http_method='POST', name='playlist.items.put',
request_fields=('myplaylist','appid')) # renamed request field
def PlaylistItemPut(self, PlaylistItem):
PlaylistItem.put()
return PlaylistItem
@PlaylistItem.query_method(path='playlist/{myplaylist}/items', name='playlist.items.list',
query_fields=('myplaylist',),) # renamed request field
def PlaylistItemList(self, query):
return query
I can also see the playlist "column" in the Datastore viewer (as you would expect, previously it was not set).
Upvotes: 1