我要建立一个Club模型,它的members类型是User。很明显,一个俱乐部可以有大量的会员。
我做过这个
class User(EndpointsModel):
username = ndb.StringProperty(required=True)
class Club(EndpointsModel):
....
members_key = ndb.KeyProperty(kind="User", repeated=True)
@EndpointsAliasProperty(repeated=True,property_type=User.ProtoModel())
def members(self):
return ndb.get_multi(self.members_key)在响应中这样做,我得到了的整个用户列表,在这种情况下,我有5000个成员可能需要一段时间。
是否有可能将此列表分页?也许用ProtoCollection()代替ProtoModel()?(我尝试了,但没有成功)。
或者,如何创建一个/club/{id}/members类型的端点来返回成员的列表(分页)?
发布于 2014-10-27 07:38:55
在这里,我做了一些测试,我找到了这个解决方案(在club/{id}/members上有这个方法)
我为标准端点创建了一个资源容器。这些消息复制query_method作为输入的内容。
ID_RESOURCE_PAGE = endpoints.ResourceContainer(
message_types.VoidMessage,
id=messages.IntegerField(1, variant=messages.Variant.INT64),
cursor=messages.StringField(2, variant=messages.Variant.STRING, required=False, default="1"),
limit=messages.IntegerField(3, variant=messages.Variant.INT32, required=False, default=10)
)然后我创建了一个像这样的标准@endopint.method
@endpoints.method(ID_RESOURCE_PAGE, User.ProtoCollection(),
path='club/{id}/members',
http_method='GET',
name='club.members')
def club_memebers(self, request):
# check if user has ownership
club = Club.get_by_id(request.id)
page_size = request.limit
# convert the cursors, usually it's a token, here is page number.
page = int(request.cursor)
# internal check, just in case.
if (page is None or page < 0):
raise endpoints.BadRequestException(message="Page field must be a positive integer")
if (page_size is None or page_size < 0 or page > 100):
raise endpoints.BadRequestException(
message="Page_size field must be a positive integer and cannot be greater than 100")
# compute start and end users to retrive
start = (page - 1) * page_size
end = page * page_size
# crop the list
res_list = club.membersUser[start:end]
# create the object
ret = User.ToMessageCollection(res_list)
# it's probably another page
if (len(res_list) == page_size):
# add next page as nextPageToken, not the best but the easy way
ret.nextPageToken = str(page + 1)
return ret请注意,我使用User.ProtoCollection()自动序列化了集合,并将页面号伪造为ret.nextPageToken。最后一次编辑看起来不太干净(实际上也不是),但是查询有效。
不过,我对这个解决方案并不满意。
发布于 2014-12-13 23:35:32
还有很多其他方法可以实现多用户对一个俱乐部的关系--我想在用户中存储一个“俱乐部”重复属性,该属性引用他们所属的俱乐部(存储俱乐部的密钥)。查询满足clubs属性的用户,并将结果限制在页面大小。使用类似的模式
next_page_results = User.all().filter('club =', club_key).filter('__key__ >', last_seen_key).order('key').run(limit=page_size)
确保正确检索页面,在正确的位置开始和停止。
(下一次调用的last_seen_key = next_page_results[-1] )
按照您所做的方式,每次获取所有结果并在内存中进行筛选。这很糟糕,而且会花你的钱。
https://stackoverflow.com/questions/26576158
复制相似问题