diff -r 261778de26ff -r 620f9b141567 thirdparty/google_appengine/lib/django/tests/modeltests/lookup/models.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thirdparty/google_appengine/lib/django/tests/modeltests/lookup/models.py Tue Aug 26 21:49:54 2008 +0000 @@ -0,0 +1,233 @@ +""" +7. The lookup API + +This demonstrates features of the database API. +""" + +from django.db import models + +class Article(models.Model): + headline = models.CharField(maxlength=100) + pub_date = models.DateTimeField() + class Meta: + ordering = ('-pub_date', 'headline') + + def __str__(self): + return self.headline + +__test__ = {'API_TESTS':r""" +# Create a couple of Articles. +>>> from datetime import datetime +>>> a1 = Article(headline='Article 1', pub_date=datetime(2005, 7, 26)) +>>> a1.save() +>>> a2 = Article(headline='Article 2', pub_date=datetime(2005, 7, 27)) +>>> a2.save() +>>> a3 = Article(headline='Article 3', pub_date=datetime(2005, 7, 27)) +>>> a3.save() +>>> a4 = Article(headline='Article 4', pub_date=datetime(2005, 7, 28)) +>>> a4.save() +>>> a5 = Article(headline='Article 5', pub_date=datetime(2005, 8, 1, 9, 0)) +>>> a5.save() +>>> a6 = Article(headline='Article 6', pub_date=datetime(2005, 8, 1, 8, 0)) +>>> a6.save() +>>> a7 = Article(headline='Article 7', pub_date=datetime(2005, 7, 27)) +>>> a7.save() + +# Each QuerySet gets iterator(), which is a generator that "lazily" returns +# results using database-level iteration. +>>> for a in Article.objects.iterator(): +... print a.headline +Article 5 +Article 6 +Article 4 +Article 2 +Article 3 +Article 7 +Article 1 + +# iterator() can be used on any QuerySet. +>>> for a in Article.objects.filter(headline__endswith='4').iterator(): +... print a.headline +Article 4 + +# count() returns the number of objects matching search criteria. +>>> Article.objects.count() +7L +>>> Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).count() +3L +>>> Article.objects.filter(headline__startswith='Blah blah').count() +0L + +# count() should respect sliced query sets. +>>> articles = Article.objects.all() +>>> articles.count() +7L +>>> articles[:4].count() +4 +>>> articles[1:100].count() +6L +>>> articles[10:100].count() +0 + +# Date and date/time lookups can also be done with strings. +>>> Article.objects.filter(pub_date__exact='2005-07-27 00:00:00').count() +3L + +# in_bulk() takes a list of IDs and returns a dictionary mapping IDs +# to objects. +>>> Article.objects.in_bulk([1, 2]) +{1: , 2: } +>>> Article.objects.in_bulk([3]) +{3: } +>>> Article.objects.in_bulk([1000]) +{} +>>> Article.objects.in_bulk([]) +{} +>>> Article.objects.in_bulk('foo') +Traceback (most recent call last): + ... +AssertionError: in_bulk() must be provided with a list of IDs. +>>> Article.objects.in_bulk() +Traceback (most recent call last): + ... +TypeError: in_bulk() takes exactly 2 arguments (1 given) +>>> Article.objects.in_bulk(headline__startswith='Blah') +Traceback (most recent call last): + ... +TypeError: in_bulk() got an unexpected keyword argument 'headline__startswith' + +# values() returns a list of dictionaries instead of object instances -- and +# you can specify which fields you want to retrieve. +>>> Article.objects.values('headline') +[{'headline': 'Article 5'}, {'headline': 'Article 6'}, {'headline': 'Article 4'}, {'headline': 'Article 2'}, {'headline': 'Article 3'}, {'headline': 'Article 7'}, {'headline': 'Article 1'}] +>>> Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).values('id') +[{'id': 2}, {'id': 3}, {'id': 7}] +>>> list(Article.objects.values('id', 'headline')) == [{'id': 5, 'headline': 'Article 5'}, {'id': 6, 'headline': 'Article 6'}, {'id': 4, 'headline': 'Article 4'}, {'id': 2, 'headline': 'Article 2'}, {'id': 3, 'headline': 'Article 3'}, {'id': 7, 'headline': 'Article 7'}, {'id': 1, 'headline': 'Article 1'}] +True + +>>> for d in Article.objects.values('id', 'headline'): +... i = d.items() +... i.sort() +... i +[('headline', 'Article 5'), ('id', 5)] +[('headline', 'Article 6'), ('id', 6)] +[('headline', 'Article 4'), ('id', 4)] +[('headline', 'Article 2'), ('id', 2)] +[('headline', 'Article 3'), ('id', 3)] +[('headline', 'Article 7'), ('id', 7)] +[('headline', 'Article 1'), ('id', 1)] + +# You can use values() with iterator() for memory savings, because iterator() +# uses database-level iteration. +>>> for d in Article.objects.values('id', 'headline').iterator(): +... i = d.items() +... i.sort() +... i +[('headline', 'Article 5'), ('id', 5)] +[('headline', 'Article 6'), ('id', 6)] +[('headline', 'Article 4'), ('id', 4)] +[('headline', 'Article 2'), ('id', 2)] +[('headline', 'Article 3'), ('id', 3)] +[('headline', 'Article 7'), ('id', 7)] +[('headline', 'Article 1'), ('id', 1)] + +# if you don't specify which fields, all are returned +>>> list(Article.objects.filter(id=5).values()) == [{'id': 5, 'headline': 'Article 5', 'pub_date': datetime(2005, 8, 1, 9, 0)}] +True + +# Every DateField and DateTimeField creates get_next_by_FOO() and +# get_previous_by_FOO() methods. +# In the case of identical date values, these methods will use the ID as a +# fallback check. This guarantees that no records are skipped or duplicated. +>>> a1.get_next_by_pub_date() + +>>> a2.get_next_by_pub_date() + +>>> a2.get_next_by_pub_date(headline__endswith='6') + +>>> a3.get_next_by_pub_date() + +>>> a4.get_next_by_pub_date() + +>>> a5.get_next_by_pub_date() +Traceback (most recent call last): + ... +DoesNotExist: Article matching query does not exist. +>>> a6.get_next_by_pub_date() + +>>> a7.get_next_by_pub_date() + + +>>> a7.get_previous_by_pub_date() + +>>> a6.get_previous_by_pub_date() + +>>> a5.get_previous_by_pub_date() + +>>> a4.get_previous_by_pub_date() + +>>> a3.get_previous_by_pub_date() + +>>> a2.get_previous_by_pub_date() + + +# Underscores and percent signs have special meaning in the underlying +# SQL code, but Django handles the quoting of them automatically. +>>> a8 = Article(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20)) +>>> a8.save() +>>> Article.objects.filter(headline__startswith='Article') +[, , , , , , , ] +>>> Article.objects.filter(headline__startswith='Article_') +[] + +>>> a9 = Article(headline='Article% with percent sign', pub_date=datetime(2005, 11, 21)) +>>> a9.save() +>>> Article.objects.filter(headline__startswith='Article') +[, , , , , , , , ] +>>> Article.objects.filter(headline__startswith='Article%') +[] + +# exclude() is the opposite of filter() when doing lookups: +>>> Article.objects.filter(headline__contains='Article').exclude(headline__contains='with') +[, , , , , , ] +>>> Article.objects.exclude(headline__startswith="Article_") +[, , , , , , , ] +>>> Article.objects.exclude(headline="Article 7") +[, , , , , , , ] + +# Backslashes also have special meaning in the underlying SQL code, but Django +# automatically quotes them appropriately. +>>> a10 = Article(headline='Article with \\ backslash', pub_date=datetime(2005, 11, 22)) +>>> a10.save() +>>> Article.objects.filter(headline__contains='\\') +[] + +# none() returns an EmptyQuerySet that behaves like any other QuerySet object +>>> Article.objects.none() +[] +>>> Article.objects.none().filter(headline__startswith='Article') +[] +>>> Article.objects.none().count() +0 +>>> [article for article in Article.objects.none().iterator()] +[] + +# using __in with an empty list should return an empty query set +>>> Article.objects.filter(id__in=[]) +[] + +>>> Article.objects.exclude(id__in=[]) +[, , , , , , , , , ] + +# Programming errors are pointed out with nice error messages +>>> Article.objects.filter(pub_date_year='2005').count() +Traceback (most recent call last): + ... +TypeError: Cannot resolve keyword 'pub_date_year' into field + +>>> Article.objects.filter(headline__starts='Article') +Traceback (most recent call last): + ... +TypeError: Cannot resolve keyword 'headline__starts' into field + +"""}