Skip to content

Commit 6825c63

Browse files
committed
Merge pull request #296 from GoogleCloudPlatform/ndb-queries
Move in ndb queries code snippets & tests
2 parents fe23eeb + 1cd17b0 commit 6825c63

File tree

10 files changed

+841
-4
lines changed

10 files changed

+841
-4
lines changed

appengine/ndb/cache/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## App Engine Datastore NDB Cache Samples
22

33
This contains snippets used in the NDB cache documentation, demonstrating
4-
various operation on ndb caches.
4+
various operations on ndb caches.
55

66
<!-- auto-doc-link -->
77
These samples are used on the following documentation page:

appengine/ndb/entities/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## App Engine Datastore NDB Entities Samples
22

33
This contains snippets used in the NDB entity documentation, demonstrating
4-
various operation on ndb entities.
4+
various operations on ndb entities.
55

66
<!-- auto-doc-link -->
77
These samples are used on the following documentation page:

appengine/ndb/properties/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## App Engine Datastore NDB Properties Samples
22

33
This contains snippets used in the NDB properties documentation, demonstrating
4-
various operation on ndb properties.
4+
various operations on ndb properties.
55

66
<!-- auto-doc-link -->
77
These samples are used on the following documentation page:

appengine/ndb/property_subclasses/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## App Engine Datastore NDB Property Subclasses Samples
22

33
This contains snippets used in the NDB property subclasses documentation,
4-
demonstrating various operation on ndb property subclasses.
4+
demonstrating various operations on ndb property subclasses.
55

66
<!-- auto-doc-link -->
77
These samples are used on the following documentation page:

appengine/ndb/queries/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## App Engine Datastore NDB Queries Samples
2+
3+
This contains snippets used in the NDB queries documentation, demonstrating
4+
various ways to make ndb queries.
5+
6+
<!-- auto-doc-link -->
7+
These samples are used on the following documentation page:
8+
9+
> https://cloud.google.com/appengine/docs/python/ndb/queries
10+
11+
<!-- end-auto-doc-link -->

appengine/ndb/queries/guestbook.py

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright 2016 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the 'License');
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an 'AS IS' BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import cgi
16+
17+
from google.appengine.datastore.datastore_query import Cursor
18+
from google.appengine.ext import ndb
19+
import webapp2
20+
21+
22+
class Greeting(ndb.Model):
23+
"""Models an individual Guestbook entry with content and date."""
24+
content = ndb.StringProperty()
25+
date = ndb.DateTimeProperty(auto_now_add=True)
26+
27+
@classmethod
28+
def query_book(cls, ancestor_key):
29+
return cls.query(ancestor=ancestor_key).order(-cls.date)
30+
31+
32+
class MainPage(webapp2.RequestHandler):
33+
GREETINGS_PER_PAGE = 20
34+
35+
def get(self):
36+
guestbook_name = self.request.get('guestbook_name')
37+
ancestor_key = ndb.Key('Book', guestbook_name or '*notitle*')
38+
greetings = Greeting.query_book(ancestor_key).fetch(
39+
self.GREETINGS_PER_PAGE)
40+
41+
self.response.out.write('<html><body>')
42+
43+
for greeting in greetings:
44+
self.response.out.write(
45+
'<blockquote>%s</blockquote>' % cgi.escape(greeting.content))
46+
47+
self.response.out.write('</body></html>')
48+
49+
50+
class List(webapp2.RequestHandler):
51+
GREETINGS_PER_PAGE = 10
52+
53+
def get(self):
54+
"""Handles requests like /list?cursor=1234567."""
55+
cursor = Cursor(urlsafe=self.request.get('cursor'))
56+
greets, next_cursor, more = Greeting.query().fetch_page(
57+
self.GREETINGS_PER_PAGE, start_cursor=cursor)
58+
59+
self.response.out.write('<html><body>')
60+
61+
for greeting in greets:
62+
self.response.out.write(
63+
'<blockquote>%s</blockquote>' % cgi.escape(greeting.content))
64+
65+
if more and next_cursor:
66+
self.response.out.write('<a href="/list?cursor=%s">More...</a>' %
67+
next_cursor.urlsafe())
68+
69+
self.response.out.write('</body></html>')
70+
71+
72+
app = webapp2.WSGIApplication([
73+
('/', MainPage),
74+
('/list', List),
75+
], debug=True)
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright 2016 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import re
16+
17+
from google.appengine.ext import ndb
18+
import guestbook
19+
import pytest
20+
import webtest
21+
22+
23+
@pytest.fixture
24+
def app(testbed):
25+
return webtest.TestApp(guestbook.app)
26+
27+
28+
def test_main(app):
29+
# Add a greeting to find
30+
guestbook.Greeting(
31+
content='Hello world',
32+
parent=ndb.Key('Book', 'brane3')).put()
33+
34+
# Add a greeting to not find.
35+
guestbook.Greeting(
36+
content='Flat sheet',
37+
parent=ndb.Key('Book', 'brane2')).put()
38+
39+
response = app.get('/?guestbook_name=brane3')
40+
41+
assert response.status_int == 200
42+
assert 'Hello world' in response.body
43+
assert 'Flat sheet' not in response.body
44+
45+
46+
def test_list(app):
47+
# Add greetings to find
48+
for i in range(11):
49+
guestbook.Greeting(content='Greeting {}'.format(i)).put()
50+
51+
response = app.get('/list')
52+
assert response.status_int == 200
53+
54+
assert 'Greeting 0' in response.body
55+
assert 'Greeting 9' in response.body
56+
assert 'Greeting 10' not in response.body
57+
58+
next_page = re.search(r'href="([^"]+)"', response.body).group(1)
59+
assert next_page is not None
60+
61+
response = app.get(next_page)
62+
assert response.status_int == 200
63+
64+
assert 'Greeting 0' not in response.body
65+
assert 'Greeting 10' in response.body
66+
assert 'More' not in response.body

0 commit comments

Comments
 (0)