1

我必須模擬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的端點,讓我回到成員列表(分頁)?

回答

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

還有許多其他的方法你可能實現衆多用戶對一個俱樂部的關係 - 我想存儲在引用他們(賣場的關鍵成員俱樂部的用戶一個「俱樂部」重複屬性該俱樂部)。您可以查詢滿足俱樂部屬性的用戶,並將結果限制爲頁面大小。使用像

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]下一次呼叫)

你的方式這樣做,你每次獲取所有結果並在內存中過濾。這很糟糕,而且會花費你的錢。

相關問題