我正在尝试使用端点来更新数据存储区中的某些JSON值。我在GAE中有以下数据存储...
class UsersList(ndb.Model):
UserID = ndb.StringProperty(required=True)
ArticlesRead = ndb.JsonProperty()
ArticlesPush = ndb.JsonProperty()
一般来说,我想用API做的是让方法接受UserID和读取的文章列表(文章由持有ID的字典和一个布尔字段表示用户是否用户喜欢这篇文章)。我的消息(以此逻辑为中心)如下......
class UserID(messages.Message):
id = messages.StringField(1, required=True)
class Articles(messages.Message):
id = messages.StringField(1, required=True)
userLiked = messages.BooleanField(2, required=True)
class UserIDAndArticles(messages.Message):
id = messages.StringField(1, required=True)
items = messages.MessageField(Articles, 2, repeated=True)
class ArticleList(messages.Message):
items = messages.MessageField(Articles, 1, repeated=True)
我尝试进行此更新的API / Endpoint方法如下......
@endpoints.method(UserIDAndArticles, ArticleList,
name='user.update',
path='update',
http_method='GET')
def get_update(self, request):
userID = request.id
articleList = request.items
queryResult = UsersList.query(UsersList.UserID == userID)
currentList = []
#This query always returns only one result back, and this for loop is the only way
# I could figure out how to access the query results.
for thing in queryResult:
currentList = json.loads(thing.ArticlesRead)
for item in articleList:
currentList.append(item)
for blah in queryResult:
blah.ArticlesRead = json.dumps(currentList)
blah.put()
for thisThing in queryResult:
pushList = json.loads(thisThing.ArticlesPush)
return ArticleList(items = pushList)
我在使用此代码时遇到两个问题。首先,我似乎无法弄清楚(使用localhost Google API Explorer)如何使用我的UserIDAndArticles类将文章列表发送到端点方法。是否可以将messages.MessageField()作为端点方法的输入?
另一个问题是我在'blah.ArticlesRead = json.dumps(currentList)'行上收到错误。当我尝试使用一些随机输入运行此方法时,我收到以下错误...
TypeError: <Articles
id: u'hi'
userLiked: False> is not JSON serializable
我知道我必须制作自己的JSON编码器来解决这个问题,但我不确定传入的request.items的格式是什么样的以及我应该如何编码它。
我是GAE和端点的新手(以及一般的这种服务器端编程),所以请耐心等待。并且非常感谢您的帮助。
答案 0 :(得分:0)
一些事情:
http_method
肯定应该是POST
,或者更好PATCH
,因为您不会覆盖所有现有值,只会修改列表,即修补。json.loads
和json.dumps
,NDB会自动为您完成。这是我提出的方法主体:
# get UsersList entity and raise an exception if none found.
uid = request.id
userlist = UsersList.query(UsersList.UserID == uid).get()
if userlist is None:
raise endpoints.NotFoundException('List for user ID %s not found' % uid)
# update user's read articles list, which is actually a dict.
for item in request.items:
userslist.ArticlesRead[item.id] = item.userLiked
userslist.put()
# assuming userlist.ArticlesPush is actually a list of article IDs.
pushItems = [Article(id=id) for id in userlist.ArticlesPush]
return ArticleList(items=pushItems)
此外,您应该将此方法包装在事务中。