Skip to content

Commit

Permalink
Merge pull request #296 from GoogleCloudPlatform/ndb-queries
Browse files Browse the repository at this point in the history
Move in ndb queries code snippets & tests
  • Loading branch information
jerjou committed Apr 28, 2016
2 parents fe23eeb + 1cd17b0 commit 6825c63
Show file tree
Hide file tree
Showing 10 changed files with 841 additions and 4 deletions.
2 changes: 1 addition & 1 deletion appengine/ndb/cache/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## App Engine Datastore NDB Cache Samples

This contains snippets used in the NDB cache documentation, demonstrating
various operation on ndb caches.
various operations on ndb caches.

<!-- auto-doc-link -->
These samples are used on the following documentation page:
Expand Down
2 changes: 1 addition & 1 deletion appengine/ndb/entities/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## App Engine Datastore NDB Entities Samples

This contains snippets used in the NDB entity documentation, demonstrating
various operation on ndb entities.
various operations on ndb entities.

<!-- auto-doc-link -->
These samples are used on the following documentation page:
Expand Down
2 changes: 1 addition & 1 deletion appengine/ndb/properties/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## App Engine Datastore NDB Properties Samples

This contains snippets used in the NDB properties documentation, demonstrating
various operation on ndb properties.
various operations on ndb properties.

<!-- auto-doc-link -->
These samples are used on the following documentation page:
Expand Down
2 changes: 1 addition & 1 deletion appengine/ndb/property_subclasses/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## App Engine Datastore NDB Property Subclasses Samples

This contains snippets used in the NDB property subclasses documentation,
demonstrating various operation on ndb property subclasses.
demonstrating various operations on ndb property subclasses.

<!-- auto-doc-link -->
These samples are used on the following documentation page:
Expand Down
11 changes: 11 additions & 0 deletions appengine/ndb/queries/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## App Engine Datastore NDB Queries Samples

This contains snippets used in the NDB queries documentation, demonstrating
various ways to make ndb queries.

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

> https://cloud.google.com/appengine/docs/python/ndb/queries
<!-- end-auto-doc-link -->
75 changes: 75 additions & 0 deletions appengine/ndb/queries/guestbook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import cgi

from google.appengine.datastore.datastore_query import Cursor
from google.appengine.ext import ndb
import webapp2


class Greeting(ndb.Model):
"""Models an individual Guestbook entry with content and date."""
content = ndb.StringProperty()
date = ndb.DateTimeProperty(auto_now_add=True)

@classmethod
def query_book(cls, ancestor_key):
return cls.query(ancestor=ancestor_key).order(-cls.date)


class MainPage(webapp2.RequestHandler):
GREETINGS_PER_PAGE = 20

def get(self):
guestbook_name = self.request.get('guestbook_name')
ancestor_key = ndb.Key('Book', guestbook_name or '*notitle*')
greetings = Greeting.query_book(ancestor_key).fetch(
self.GREETINGS_PER_PAGE)

self.response.out.write('<html><body>')

for greeting in greetings:
self.response.out.write(
'<blockquote>%s</blockquote>' % cgi.escape(greeting.content))

self.response.out.write('</body></html>')


class List(webapp2.RequestHandler):
GREETINGS_PER_PAGE = 10

def get(self):
"""Handles requests like /list?cursor=1234567."""
cursor = Cursor(urlsafe=self.request.get('cursor'))
greets, next_cursor, more = Greeting.query().fetch_page(
self.GREETINGS_PER_PAGE, start_cursor=cursor)

self.response.out.write('<html><body>')

for greeting in greets:
self.response.out.write(
'<blockquote>%s</blockquote>' % cgi.escape(greeting.content))

if more and next_cursor:
self.response.out.write('<a href="/list?cursor=%s">More...</a>' %
next_cursor.urlsafe())

self.response.out.write('</body></html>')


app = webapp2.WSGIApplication([
('/', MainPage),
('/list', List),
], debug=True)
66 changes: 66 additions & 0 deletions appengine/ndb/queries/guestbook_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import re

from google.appengine.ext import ndb
import guestbook
import pytest
import webtest


@pytest.fixture
def app(testbed):
return webtest.TestApp(guestbook.app)


def test_main(app):
# Add a greeting to find
guestbook.Greeting(
content='Hello world',
parent=ndb.Key('Book', 'brane3')).put()

# Add a greeting to not find.
guestbook.Greeting(
content='Flat sheet',
parent=ndb.Key('Book', 'brane2')).put()

response = app.get('/?guestbook_name=brane3')

assert response.status_int == 200
assert 'Hello world' in response.body
assert 'Flat sheet' not in response.body


def test_list(app):
# Add greetings to find
for i in range(11):
guestbook.Greeting(content='Greeting {}'.format(i)).put()

response = app.get('/list')
assert response.status_int == 200

assert 'Greeting 0' in response.body
assert 'Greeting 9' in response.body
assert 'Greeting 10' not in response.body

next_page = re.search(r'href="([^"]+)"', response.body).group(1)
assert next_page is not None

response = app.get(next_page)
assert response.status_int == 200

assert 'Greeting 0' not in response.body
assert 'Greeting 10' in response.body
assert 'More' not in response.body
Loading

0 comments on commit 6825c63

Please sign in to comment.