我要为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)
。显然俱乐部可能会有很多会员。
我已经完成了这个
ProtoCollection()
在回复中我这样做了整个用户列表,在这种情况下,我有5000名会员需要一段时间。
是否有可能将此列表分页?可能使用ProtoModel()
代替/club/{id}/members
? (我尝试没有成功)。
或者,我如何创建{{1}}类型的端点,让我返回成员列表(分页)?
答案 0 :(得分:1)
我在这里。我做了一些测试,我发现了这个解决方案(方法是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
。最后一次编辑看起来不太干净(实际上并非如此),但查询有效。
尽管如此,我对此解决方案并不满意。
答案 1 :(得分:1)
还有很多其他方法可以实现多用户对一个俱乐部的关系 - 我想过存储一个&#34;俱乐部&#34;用户中重复的属性,引用他们所属的俱乐部(存储俱乐部的密钥)。您查询满足俱乐部属性的用户,并将结果限制为页面大小。使用类似
的模式 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]
用于下次通话)
您执行此操作的方式,每次都会获取所有结果并在内存中进行过滤。这很糟糕,而且会花钱。