| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta http-equiv="content-type" content="text/html;charset=utf-8"> |
| <title>keys_with_ancestors</title> |
| <link rel="stylesheet" href="/css/pycco.css"> |
| </head> |
| <body> |
| <div id="background"></div> |
| <div id='container'> |
| <div class='section'> |
| <div class='docs'><h1>keys_with_ancestors</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/matching_queries_to_indexes.html">matching_queries_to_indexes</a> and |
| <a href="/examples/custom_alias_properties.html">custom_alias_properties</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 define an <code>EndpointsAliasProperty</code> which does not override |
| one of the helper properties provided by <code>EndpointsModel</code>; this is a first as |
| all the other samples have simply tweaked existing alias properties. We use |
| this property in conjuction with another alias property to define entity keys |
| which have an ancestor — for example |
| <br><code>ndb.Key(MyParent, ..., MyModel, ...)</code><br> |
| — which is slightly more complex than the keys we have seen so far.</p> |
| |
| <p>We define an extra model <code>MyParent</code> to hold all the data for the ancestors being |
| used (though this is not strictly necessary, an ancestor key does not need to |
| exist in the datastore to be used). In addition, since we will be requiring |
| that a <code>MyParent</code> entity exists to be used as an ancestor, we provide a method |
| <code>MyParentInsert</code> to allow API users to create or update parent objects.</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></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>See <a href="/examples/matching_queries_to_indexes.html">matching_queries_to_indexes</a> for reference on this import.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre><span class="kn">from</span> <span class="nn">endpoints_proto_datastore.ndb</span> <span class="kn">import</span> <span class="n">EndpointsAliasProperty</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="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">MyParent</span><span class="p">(</span><span class="n">EndpointsModel</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>As in <a href="/examples/simple_get.html">simple_get</a>, by setting <code>_message_fields_schema</code>, we can set a |
| custom ProtoRPC message schema. We set the schema to the alias property |
| <code>name</code> and ignore the NDB property <code>updated</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="n">_message_fields_schema</span> <span class="o">=</span> <span class="p">(</span><span class="s">'name'</span><span class="p">,)</span> |
| |
| </pre></div> |
| </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> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="n">updated</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</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span></pre></div> |
| </div> |
| </div> |
| |
| |
| <div class='clearall'></div> |
| <div class='section' id='section-7'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-7'>#</a> |
| </div> |
| <p>This is a setter which will be used by the alias property <code>name</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">def</span> <span class="nf">NameSet</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-8'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-8'>#</a> |
| </div> |
| <p>The property <code>name</code> is a string field, so we expect a value passed in from |
| a ProtoRPC message to be a string. Since (as seen below), <code>name</code> is |
| required, we also need not worry about the case that the value is <code>None</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">basestring</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s">'Name must be a string.'</span><span class="p">)</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-9'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-9'>#</a> |
| </div> |
| <p>We update the key using the <code>name</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">UpdateFromKey</span><span class="p">(</span><span class="n">ndb</span><span class="o">.</span><span class="n">Key</span><span class="p">(</span><span class="n">MyParent</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-10'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-10'>#</a> |
| </div> |
| <p>This <code>EndpointsAliasProperty</code> is used for the property <code>name</code>. It is required, |
| meaning that a value must always be set if the corresponding field is |
| contained in a ProtoRPC message schema.</p> |
| |
| <p>Since no <code>property_type</code> is specified, the default value of |
| <code>messages.StringField</code> is used.</p> |
| |
| <p>See <a href="/examples/matching_queries_to_indexes.html">matching_queries_to_indexes</a> for more information on <code>EndpointsAliasProperty</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="nd">@EndpointsAliasProperty</span><span class="p">(</span><span class="n">setter</span><span class="o">=</span><span class="n">NameSet</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> |
| <span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-11'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-11'>#</a> |
| </div> |
| <p>First check if the entity has a key.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-12'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-12'>#</a> |
| </div> |
| <p>If the entity has a key, return only the <code>string_id</code> since the property is |
| a string field.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">string_id</span><span class="p">()</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-13'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-13'>#</a> |
| </div> |
| |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre><span class="k">class</span> <span class="nc">MyModel</span><span class="p">(</span><span class="n">EndpointsModel</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-14'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-14'>#</a> |
| </div> |
| <p>These values are placeholders to be used when a key is created; the <code>_parent</code> |
| will be used as the ancestor and the <code>_id</code> as the ID. For example: |
| <br> <code>ndb.Key(MyParent, _parent, MyModel, _id)</code><br> |
| Since these values will be set by alias properties which are not set |
| simultaneously, we need to hold them around until both are present before we |
| can create a key from them.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="n">_parent</span> <span class="o">=</span> <span class="bp">None</span> |
| <span class="n">_id</span> <span class="o">=</span> <span class="bp">None</span> |
| |
| </pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-15'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-15'>#</a> |
| </div> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> |
| <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></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-16'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-16'>#</a> |
| </div> |
| <p>This is a helper method that will set the key on the entity only if both the |
| parent and ID are present. It will be used by property setters that provide |
| values for <code>_parent</code> and <code>_id</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">def</span> <span class="nf">SetKey</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-17'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-17'>#</a> |
| </div> |
| <p>Can only set the key if both the parent and the child ID are set.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> |
| <span class="n">key</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">Key</span><span class="p">(</span><span class="n">MyParent</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="p">,</span> <span class="n">MyModel</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_id</span><span class="p">)</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-18'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-18'>#</a> |
| </div> |
| <p>Will set the key and attempt to update the entity if it exists.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">UpdateFromKey</span><span class="p">(</span><span class="n">key</span><span class="p">)</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-19'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-19'>#</a> |
| </div> |
| <p>This is a helper method that will set the <code>_parent</code> and <code>_id</code> values using the |
| entity key, if it exists. It will be used by property getters that retrieve |
| the current values of <code>_parent</code> and <code>_id</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">def</span> <span class="nf">SetParts</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-20'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-20'>#</a> |
| </div> |
| <p>If there is no key, nothing can be set.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-21'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-21'>#</a> |
| </div> |
| <p>If there are not two tuples in the key <code>pairs</code>, a <code>ValueError</code> will occur.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="n">parent_pair</span><span class="p">,</span> <span class="n">id_pair</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">pairs</span><span class="p">()</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-22'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-22'>#</a> |
| </div> |
| <p>Each pair in key <code>pairs</code> will be a tuple (model kind, value) where model |
| kind is a string representing the name of the model and value is the |
| actual string or integer ID that was set.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="o">=</span> <span class="n">parent_pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="o">=</span> <span class="n">id_pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-23'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-23'>#</a> |
| </div> |
| <p>This is a setter which will be used by the alias property <code>parent</code>. This |
| method will be called when <code>_parent</code> is set from a ProtoRPC request.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">def</span> <span class="nf">ParentSet</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-24'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-24'>#</a> |
| </div> |
| <p>The property <code>parent</code> is a string field, so we expect a value passed in |
| from a ProtoRPC message to be a string. Since (as seen below), <code>parent</code> is |
| required, we also need not worry about the case that the value is <code>None</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">basestring</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s">'Parent name must be a string.'</span><span class="p">)</span> |
| |
| </pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-25'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-25'>#</a> |
| </div> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="o">=</span> <span class="n">value</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-26'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-26'>#</a> |
| </div> |
| <p>After setting the value, we must make sure the parent exists before it can |
| be used as an ancestor.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="n">ndb</span><span class="o">.</span><span class="n">Key</span><span class="p">(</span><span class="n">MyParent</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">()</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-27'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-27'>#</a> |
| </div> |
| <p>If the <code>MyParent</code> key does not correspond to an entity in the datastore, |
| we return an HTTP 404 Not Found.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">raise</span> <span class="n">endpoints</span><span class="o">.</span><span class="n">NotFoundException</span><span class="p">(</span><span class="s">'Parent </span><span class="si">%s</span><span class="s"> does not exist.'</span> <span class="o">%</span> <span class="n">value</span><span class="p">)</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-28'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-28'>#</a> |
| </div> |
| <p>The helper method <code>SetKey</code> is called to set the entity key if the <code>_id</code> has |
| also been set already.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">SetKey</span><span class="p">()</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-29'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-29'>#</a> |
| </div> |
| <p>If the <code>parent</code> property is used in a query method, we want the ancestor |
| of the query to be the parent key.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">_endpoints_query_info</span><span class="o">.</span><span class="n">ancestor</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">Key</span><span class="p">(</span><span class="n">MyParent</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-30'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-30'>#</a> |
| </div> |
| <p>This <code>EndpointsAliasProperty</code> is used to get and set a parent for our entity |
| key. It is required, meaning that a value must always be set if the |
| corresponding field is contained in a ProtoRPC message schema.</p> |
| |
| <p>Since no <code>property_type</code> is specified, the default value of |
| <code>messages.StringField</code> is used.</p> |
| |
| <p>See <a href="/examples/matching_queries_to_indexes.html">matching_queries_to_indexes</a> for more information on <code>EndpointsAliasProperty</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="nd">@EndpointsAliasProperty</span><span class="p">(</span><span class="n">setter</span><span class="o">=</span><span class="n">ParentSet</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> |
| <span class="k">def</span> <span class="nf">parent</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-31'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-31'>#</a> |
| </div> |
| <p>If <code>_parent</code> has not already been set on the entity, try to set it.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-32'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-32'>#</a> |
| </div> |
| <p>Using the helper method <code>SetParts</code>, <code>_parent</code> will be set if a valid key has |
| been set on the entity.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">SetParts</span><span class="p">()</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-33'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-33'>#</a> |
| </div> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-34'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-34'>#</a> |
| </div> |
| <p>This is a setter which will be used by the alias property <code>id</code>. This |
| method will be called when <code>_id</code> is set from a ProtoRPC request. This replaces |
| the helper property <code>id</code> provided by <code>EndpointsModel</code>, but does not use any of |
| the functionality from that method.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">def</span> <span class="nf">IdSet</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-35'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-35'>#</a> |
| </div> |
| <p>The property <code>id</code> is a string field, so we expect a value passed in from a |
| ProtoRPC message to be a string. Since (as seen below), <code>id</code> is required, |
| we also need not worry about the case that the value is <code>None</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">basestring</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s">'ID must be a string.'</span><span class="p">)</span> |
| |
| </pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-36'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-36'>#</a> |
| </div> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="o">=</span> <span class="n">value</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-37'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-37'>#</a> |
| </div> |
| <p>The helper method <code>SetKey</code> is called to set the entity key if the <code>_parent</code> |
| has also been set already.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">SetKey</span><span class="p">()</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-38'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-38'>#</a> |
| </div> |
| <p>This <code>EndpointsAliasProperty</code> is used to get and set an <code>id</code> value for our |
| entity key. It is required, meaning that a value must always be set if the |
| corresponding field is contained in a ProtoRPC message schema.</p> |
| |
| <p>Since no <code>property_type</code> is specified, the default value of |
| <code>messages.StringField</code> is used.</p> |
| |
| <p>See <a href="/examples/matching_queries_to_indexes.html">matching_queries_to_indexes</a> for more information on <code>EndpointsAliasProperty</code>.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="nd">@EndpointsAliasProperty</span><span class="p">(</span><span class="n">setter</span><span class="o">=</span><span class="n">IdSet</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> |
| <span class="k">def</span> <span class="nf">id</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-39'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-39'>#</a> |
| </div> |
| <p>If <code>_id</code> has not already been set on the entity, try to set it.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-40'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-40'>#</a> |
| </div> |
| <p>Using the helper method <code>SetParts</code>, <code>_id</code> will be set if a valid key has |
| been set on the entity.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">SetParts</span><span class="p">()</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-41'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-41'>#</a> |
| </div> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_id</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></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-42'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-42'>#</a> |
| </div> |
| <p>This method is not defined in any of the previous examples; it allows a |
| parent entity to be inserted so that it can be used as an ancestor. Since |
| the ProtoRPC message schema for <code>MyParent</code> is a single field <code>name</code>, this will |
| be all that is contained in the request and the response.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="nd">@MyParent.method</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s">'myparent'</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">'myparent.insert'</span><span class="p">)</span> |
| <span class="k">def</span> <span class="nf">MyParentInsert</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">my_parent</span><span class="p">):</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-43'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-43'>#</a> |
| </div> |
| <p>Though we don't actively change the model passed in, the value of <code>updated</code> |
| is set to the current time. No check is performed to see if the <code>MyParent</code> |
| entity already exists, since the values other than the <code>name</code> (set in the |
| key) are not relevant.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="n">my_parent</span><span class="o">.</span><span class="n">put</span><span class="p">()</span> |
| <span class="k">return</span> <span class="n">my_parent</span></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-44'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-44'>#</a> |
| </div> |
| <p>Since we require <code>MyModel</code> instances also have a <code>MyParent</code> ancestor, we include |
| <code>parent</code> in the request path by setting <code>path='mymodel/{parent}'</code>. Since <code>id</code> |
| is also required, an <code>id</code> must be included in the request body or it will be |
| rejected by ProtoRPC before this method is called.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="nd">@MyModel.method</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s">'mymodel/{parent}'</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></pre></div> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| <div class='section' id='section-45'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-45'>#</a> |
| </div> |
| <p>If the entity already exists (as evidenced by <code>from_datastore</code> equal to |
| <code>True</code>), an HTTP 400 Bad Request is returned. Since both <code>parent</code> and <code>id</code> |
| are required fields, both <code>_parent</code> and <code>_id</code> will be set on the entity and |
| <code>MyModel.SetKey</code> must have been called.</p> |
| |
| <p>Checking in this fashion is not truly safe against duplicates. To do this, |
| a datastore transaction would be necessary.</p> |
| </div> |
| <div class='code'> |
| <div class="highlight"><pre> <span class="k">if</span> <span class="n">my_model</span><span class="o">.</span><span class="n">from_datastore</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="n">endpoints</span><span class="o">.</span><span class="n">BadRequestException</span><span class="p">(</span> |
| <span class="s">'MyModel </span><span class="si">%s</span><span class="s"> with parent </span><span class="si">%s</span><span class="s"> already exists.'</span> <span class="o">%</span> |
| <span class="p">(</span><span class="n">my_model</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">my_model</span><span class="o">.</span><span class="n">parent</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-46'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-46'>#</a> |
| </div> |
| <p>To make sure queries have a specified ancestor, we use the alias property |
| <code>parent</code> which we defined on <code>MyModel</code> and specify <code>query_fields</code> equal to |
| <code>('parent',)</code>. To specify the parent in the query, it is included in the path |
| as it was in <code>MyModelInsert</code>. So no query parameters will be required, simply |
| a request to |
| <br> <code>.../mymodels/someparent</code><br> |
| where <code>...</code> is the full path to the API.</p> |
| </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">'parent'</span><span class="p">,),</span> |
| <span class="n">path</span><span class="o">=</span><span class="s">'mymodels/{parent}'</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-47'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-47'>#</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-48'> |
| <div class='docs'> |
| <div class='octowrap'> |
| <a class='octothorpe' href='#section-48'>#</a> |
| </div> |
| <p>That is all for now. More examples to come. Stay tuned. |
| Head back to the <a href="/">main page</a> if you like.</p> |
| </div> |
| </div> |
| <div class='clearall'></div> |
| </div> |
| </body> |