| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta http-equiv="content-type" content="text/html;charset=utf-8"> |
| <title>paging</title> |
| <link rel="stylesheet" href="/css/pycco.css"> |
| </head> |
| <body> |
| <div id="background"></div> |
| <div id='container'> |
| <div class='section'> |
| <div class='docs'><h1>paging</h1></div> |
| </div> |
| <div class='clearall'> |
| <div class='section' id='section-0'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-0'>#</a> |
| </div> |
| <p>If you have not yet seen the source in <a href="/examples/basic.html">basic</a>, please take a look.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-1'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-1'>#</a> |
| </div> |
| <p>In this sample we modify the query parameters in the <code>MyModelList</code> method to |
| allow paging through results.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-2'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-2'>#</a> |
| </div> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre><span class="kn">import</span> <span class="n">endpoints</span> |
| <span class="kn">from</span> <span class="nn">google.appengine.ext</span> <span class="kn">import</span> <span class="n">ndb</span> |
| <span class="kn">from</span> <span class="nn">protorpc</span> <span class="kn">import</span> <span class="n">remote</span> |
| |
| <span class="kn">from</span> <span class="nn">endpoints_proto_datastore.ndb</span> <span class="kn">import</span> <span class="n">EndpointsModel</span> |
| |
| <span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">EndpointsModel</span><span class="p">):</span> |
| <span class="n">attr1</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">StringProperty</span><span class="p">()</span> |
| <span class="n">attr2</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">StringProperty</span><span class="p">()</span> |
| <span class="n">created</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">DateTimeProperty</span><span class="p">(</span><span class="n">auto_now_add</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> |
| |
| |
| <span class="nd">@endpoints.api</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">'myapi'</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="s">'v1'</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s">'My Little API'</span><span class="p">)</span> |
| <span class="k">class</span> <span class="nc">MyApi</span><span class="p">(</span><span class="n">remote</span><span class="o">.</span><span class="n">Service</span><span class="p">):</span> |
| |
| <span class="nd">@MyModel.method</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s">'mymodel'</span><span class="p">,</span> <span class="n">http_method</span><span class="o">=</span><span class="s">'POST'</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">'mymodel.insert'</span><span class="p">)</span> |
| <span class="k">def</span> <span class="nf">MyModelInsert</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">my_model</span><span class="p">):</span> |
| <span class="n">my_model</span><span class="o">.</span><span class="n">put</span><span class="p">()</span> |
| <span class="k">return</span> <span class="n">my_model</span> |
| </pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-3'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-3'>#</a> |
| </div> |
| <p>To add paging functionality, we set the keyword argument <code>query_fields</code> in the |
| <code>MyModel.query_method</code> decorator. By specifying the fields <code>limit</code>, <code>order</code> |
| and <code>pageToken</code> as the query fields, we can accept values specializing the |
| query before retrieving results from the datastore. Though <code>limit</code>, <code>order</code> |
| and <code>pageToken</code> are not defined as properties on <code>MyModel</code>, they are included |
| as helper properties by the base class <code>EndpointsModel</code>.</p> |
| |
| <p>The three helper properties we use here perform the following</p> |
| |
| <ul> |
| <li><code>limit</code>: Allows a limit to be set for the number of results retrieved by a |
| query.</li> |
| |
| <li><code>order</code>: This allows the result set to be ordered by properties. For |
| example, if the value of <code>order</code> is <code>'attr1'</code>, results of the query |
| will be in ascending order, ordered by <code>attr1</code>. Similarly, if the |
| value of <code>order</code> is <code>'-attr2'</code>, the results of the query will be in |
| descending order, ordered by <code>attr2</code>.<br><br> |
| Even more complex orders can be created, such as <code>'attr1,-attr2'</code>, |
| which will first order by <code>attr1</code> and then within each value order by |
| <code>attr2</code>. However, such queries are not possible in the datastore if |
| no index has been built. See <a href="/examples/custom_alias_properties.html">custom_alias_properties</a> and |
| <a href="/examples/matching_queries_to_indexes.html">matching_queries_to_indexes</a> for examples of how to deal with complex |
| queries.</li> |
| |
| <li><code>pageToken</code>: This is used for paging within a result set. For example, if a |
| <code>limit</code> of <code>10</code> is set, but there are <code>12</code> results, then the ProtoRPC |
| response will have <code>items</code> with <code>10</code> values and a <code>nextPageToken</code> |
| which contains a string cursor for the query. By using this |
| value as <code>pageToken</code> in a subsequent query, the remaining <code>2</code> |
| results can be retrieved and the ProtoRPC response will not |
| contain a <code>nextPageToken</code> since there are no more results.</li> |
| </ul> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="nd">@MyModel.query_method</span><span class="p">(</span><span class="n">query_fields</span><span class="o">=</span><span class="p">(</span><span class="s">'limit'</span><span class="p">,</span> <span class="s">'order'</span><span class="p">,</span> <span class="s">'pageToken'</span><span class="p">),</span> |
| <span class="n">path</span><span class="o">=</span><span class="s">'mymodels'</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">'mymodel.list'</span><span class="p">)</span> |
| <span class="k">def</span> <span class="nf">MyModelList</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">query</span><span class="p">):</span> |
| <span class="k">return</span> <span class="n">query</span> |
| |
| </pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-4'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-4'>#</a> |
| </div> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> |
| <span class="n">application</span> <span class="o">=</span> <span class="n">endpoints</span><span class="o">.</span><span class="n">api_server</span><span class="p">([</span><span class="n">MyApi</span><span class="p">],</span> <span class="n">restricted</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> |
| |
| </pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-5'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-5'>#</a> |
| </div> |
| <p>For a bit more on the other helper properties provided by <code>EndpointsModel</code>, |
| see <a href="/examples/simple_get.html">simple_get</a>. To see how to define your own helper properties, see |
| <a href="/examples/custom_alias_properties.html">custom_alias_properties</a>, <a href="/examples/matching_queries_to_indexes.html">matching_queries_to_indexes</a> and |
| <a href="/examples/keys_with_ancestors.html">keys_with_ancestors</a>.</p> |
| |
| <p>To see how query fields can be used to perform simple equality filters, see |
| <a href="/examples/property_filters.html">property_filters</a>.</p> |
| |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-6'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-6'>#</a> |
| </div> |
| <p>Head on to the next sample <a href="/examples/property_filters.html">property_filters<a> |
| or head back to the <a href="/">main page</a>.</p> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| </div> |
| </body> |